Skip to content

Commit 398cf0b

Browse files
committed
Solve 2024 day 17 part 1
1 parent 30f7a97 commit 398cf0b

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Register A: 30344604
2+
Register B: 0
3+
Register C: 0
4+
5+
Program: 2,4,1,1,7,5,1,5,4,5,0,3,5,5,3,0
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package eu.sim642.adventofcode2024
2+
3+
object Day17 {
4+
5+
case class Registers(a: Int, b: Int, c: Int)
6+
7+
type Program = Seq[Int]
8+
9+
case class Input(registers: Registers, program: Program)
10+
11+
def runOutput(input: Input): String = {
12+
val Input(registers, program) = input
13+
14+
def helper(ip: Int, registers: Registers): LazyList[Int] = {
15+
println(ip)
16+
println(registers)
17+
18+
def combo(operand: Int): Int = operand match {
19+
case 0 | 1 | 2 | 3 => operand
20+
case 4 => registers.a
21+
case 5 => registers.b
22+
case 6 => registers.c
23+
case 7 => throw new IllegalArgumentException("illegal combo operand")
24+
}
25+
26+
// 0, 5, 3
27+
// 2 1 7 4
28+
29+
if (program.indices.contains(ip)) {
30+
lazy val literalOperand = program(ip + 1)
31+
lazy val comboOperand = combo(literalOperand)
32+
33+
program(ip) match {
34+
case 0 => // adv
35+
helper(ip + 2, registers.copy(a = registers.a / (1 << comboOperand)))
36+
case 1 => // bxl
37+
helper(ip + 2, registers.copy(b = registers.b ^ literalOperand))
38+
case 2 => // bst
39+
helper(ip + 2, registers.copy(b = comboOperand & 0b111))
40+
case 3 => // jnz
41+
helper(if (registers.a != 0) literalOperand else ip + 2, registers)
42+
case 4 => // bxc
43+
helper(ip + 2, registers.copy(b = registers.b ^ registers.c))
44+
case 5 => // out
45+
(comboOperand & 0b111) +: helper(ip + 2, registers)
46+
case 6 => // bdv
47+
helper(ip + 2, registers.copy(b = registers.a / (1 << comboOperand)))
48+
case 7 => // cdv
49+
helper(ip + 2, registers.copy(c = registers.a / (1 << comboOperand)))
50+
case _ => throw new IllegalArgumentException("illegal instruction")
51+
}
52+
}
53+
else
54+
LazyList.empty
55+
}
56+
57+
helper(0, registers).mkString(",")
58+
}
59+
60+
def parseInput(input: String): Input = input match {
61+
case s"Register A: $a\nRegister B: $b\nRegister C: $c\n\nProgram: $programStr" =>
62+
val registers = Registers(a.toInt, b.toInt, c.toInt)
63+
val program = programStr.split(",").map(_.toInt).toSeq
64+
Input(registers, program)
65+
}
66+
67+
lazy val input: String = scala.io.Source.fromInputStream(getClass.getResourceAsStream("day17.txt")).mkString.trim
68+
69+
def main(args: Array[String]): Unit = {
70+
println(runOutput(parseInput(input)))
71+
72+
// part 1: 4,5,0,4,7,4,3,0,0 - wrong (bst used literal not combo operand)
73+
}
74+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package eu.sim642.adventofcode2024
2+
3+
import Day17._
4+
import org.scalatest.funsuite.AnyFunSuite
5+
6+
class Day17Test extends AnyFunSuite {
7+
8+
// TODO: small examples
9+
10+
val exampleInput =
11+
"""Register A: 729
12+
|Register B: 0
13+
|Register C: 0
14+
|
15+
|Program: 0,1,5,4,3,0""".stripMargin
16+
17+
val exampleInput1 =
18+
"""Register A: 10
19+
|Register B: 0
20+
|Register C: 0
21+
|
22+
|Program: 5,0,5,1,5,4""".stripMargin
23+
24+
val exampleInput2 =
25+
"""Register A: 2024
26+
|Register B: 0
27+
|Register C: 0
28+
|
29+
|Program: 0,1,5,4,3,0""".stripMargin
30+
31+
test("Part 1 examples") {
32+
assert(runOutput(parseInput(exampleInput)) == "4,6,3,5,6,3,5,2,1,0")
33+
assert(runOutput(parseInput(exampleInput1)) == "0,1,2")
34+
assert(runOutput(parseInput(exampleInput2)) == "4,2,5,6,7,7,7,7,3,1,0")
35+
}
36+
37+
test("Part 1 input answer") {
38+
assert(runOutput(parseInput(input)) == "4,3,2,6,4,5,3,2,4")
39+
}
40+
}

0 commit comments

Comments
 (0)