This repository was archived by the owner on Aug 21, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay21.scala
82 lines (67 loc) · 2.16 KB
/
Day21.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
package adventofcode.solutions
import adventofcode.Day
import scala.collection.BitSet
object Day21 extends Day(21) {
val nRegisters = 6
type Registers = IndexedSeq[Int]
val (ipRegex, instructionRegex) = ("#ip (\\d+)".r, "([a-z]+) (\\d+) (\\d+) (\\d+)".r)
val ip = lines.head match {
case ipRegex(reg) => reg.toInt
}
val program = lines.tail.map {
case instructionRegex(opCode, as, bs, cs) =>
def b2i(b: Boolean): Int = if(b) 1 else 0
val (a, b, c) = (as.toInt, bs.toInt, cs.toInt)
val op: Registers => Int = opCode match {
case "addr" => r => r(a) + r(b)
case "addi" => r => r(a) + b
case "mulr" => r => r(a) * r(b)
case "muli" => r => r(a) * b
case "banr" => r => r(a) & r(b)
case "bani" => r => r(a) & b
case "borr" => r => r(a) | r(b)
case "bori" => r => r(a) | b
case "setr" => r => r(a)
case "seti" => r => a
case "gtir" => r => b2i(a > r(b))
case "gtri" => r => b2i(r(a) > b)
case "gtrr" => r => b2i(r(a) > r(b))
case "eqir" => r => b2i(a == r(b))
case "eqri" => r => b2i(r(a) == b)
case "eqrr" => r => b2i(r(a) == r(b))
}
(r: Registers) => r.updated(c, op(r))
}
def next(r: Registers): Option[Registers] = {
val i = r(ip)
if(i < program.size) {
val executed = program(i)(r)
val incremented = executed.updated(ip, executed(ip) + 1)
Some(incremented)
} else {
None
}
}
val initial: Registers = IndexedSeq.fill(nRegisters)(0)
val (magicLine, magicRegister) = (28, 3)
def findSmallestHalt(r: Registers): Int = {
val i = r(ip)
if(i != magicLine)
findSmallestHalt(next(r).get)
else
r(magicRegister)
}
override def solutionA = findSmallestHalt(initial)
def findLargestHalt(r: Registers, seen: BitSet, previous: Int): Int = {
val i = r(ip)
val v = r(magicRegister)
if(i != magicLine)
findLargestHalt(next(r).get, seen, previous)
else if(!seen.contains(v))
findLargestHalt(next(r).get, seen + v, v)
else
previous
}
override def solutionB = findLargestHalt(initial, BitSet.empty, 0)
submit()
}