-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday10.sc
61 lines (48 loc) · 1.46 KB
/
day10.sc
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
// scala 2.13.6
import ammonite.ops._
import $file.runner
runner.exec[Long]("day10") { (fileName, assert) =>
val entries = read.lines(pwd / fileName).toList
val syntax = Map('<' -> '>', '(' -> ')', '[' -> ']', '{' -> '}')
object Open {
def unapply(c: Char): Option[Char] = syntax.keySet.find(_ == c)
}
trait Result
case class Remaining(r: List[Char]) extends Result
case class Unexpected(c: Char) extends Throwable with Result
def parseLine(line: String) =
line.foldLeft(List.empty[Char]) {
case (sofar, Open(next)) => next :: sofar
case (last :: rest, next) =>
if (syntax(last) == next) rest
else throw Unexpected(next)
}
def lineResult(line: String) =
try {
Remaining(parseLine(line))
} catch {
case u: Unexpected => u
}
val parsed = entries.map(lineResult)
val errorScore = parsed.collect {
case Unexpected(')') => 3
case Unexpected(']') => 57
case Unexpected('}') => 1197
case Unexpected('>') => 25137
case _ => 0
}.sum
assert("total error score", 26397, 168417)(errorScore)
val autocompleteScores = parsed.collect { case Remaining(r) =>
r.foldLeft(0L) { (score, char) =>
score * 5 + (syntax(char) match {
case ')' => 1
case ']' => 2
case '}' => 3
case '>' => 4
})
}
}.sorted
assert("autocomplete score", 288957, 2802519786L) {
autocompleteScores.drop(autocompleteScores.size / 2).head
}
}