-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day10.scala
84 lines (75 loc) · 2.38 KB
/
Day10.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package com.kensai.aoc.aoc2021
object Day10 {
case class Chunk(
open: Char,
close: Char,
corruptedScore: Int,
incompleteScore: Int)
val allChunks: Seq[Chunk] = Seq(
Chunk('(', ')', 3, 1),
Chunk('{', '}', 1197, 3),
Chunk('[', ']', 57, 2),
Chunk('<', '>', 25137, 4)
)
private def parseLines(lines: Seq[String]): Seq[Seq[Char]] =
lines.collect {
case str if str.nonEmpty => str.trim
}.map(_.toCharArray.toSeq)
def computeCorruptedSyntaxScore(lines: Seq[String]): Int = {
val inputs = parseLines(lines)
inputs.map(line => doComputeCorruptedSyntaxScore(line, Seq())).sum
}
private def doComputeCorruptedSyntaxScore(
line: Seq[Char],
openChars: Seq[Char]
): Int = line match {
case Nil => 0
case head +: tail =>
val chunk = allChunks.find(c => c.open == head || c.close == head).get
if (chunk.open == head)
doComputeCorruptedSyntaxScore(tail, head +: openChars)
else {
if (openChars.head == chunk.open) {
doComputeCorruptedSyntaxScore(tail, openChars.tail)
} else {
chunk.corruptedScore
}
}
case _ =>
???
}
def doComputeIncompleteSyntaxScore(
line: Seq[Char],
openChars: Seq[Char]
): Seq[Int] = line match {
case Nil =>
openChars
.flatMap(c => allChunks.find(_.open == c))
.map(chunk => chunk.incompleteScore)
case head +: tail =>
val chunk = allChunks.find(c => c.open == head || c.close == head).get
if (chunk.open == head)
doComputeIncompleteSyntaxScore(tail, head +: openChars)
else {
if (openChars.head == chunk.open) {
doComputeIncompleteSyntaxScore(tail, openChars.tail)
} else {
Seq() // Corrupted line
}
}
case _ =>
// Should not happen
???
}
def computeIncompleteSyntaxScore(lines: Seq[String]): Seq[Long] = {
val inputs = parseLines(lines)
val incompleteLines = inputs
.map(line => doComputeIncompleteSyntaxScore(line, Seq()))
.filterNot(_.isEmpty)
incompleteLines.map(incompleteLine => incompleteLine.foldLeft(0L) { case (acc, right) => 5L * acc + right })
}
def computeMiddleIncompleteSyntaxScore(lines: Seq[String]): Long = {
val incompleteScores = computeIncompleteSyntaxScore(lines)
incompleteScores.sorted.apply(incompleteScores.size / 2)
}
}