This commit is contained in:
Christian
2024-12-17 12:49:00 +01:00
parent f703a5f028
commit e435a7b160
4 changed files with 87 additions and 1 deletions

View File

@@ -18,7 +18,8 @@ val solvers = Map[Int, Solver](
13 -> Day13, 13 -> Day13,
14 -> Day14, 14 -> Day14,
15 -> Day15, 15 -> Day15,
16 -> Day16 16 -> Day16,
17 -> Day17
) )
def runSolver(solver: Solver, input: os.Path): Unit = def runSolver(solver: Solver, input: os.Path): Unit =

View File

@@ -0,0 +1,78 @@
package dev.ctsk.aoc.days
import dev.ctsk.aoc.*
import scala.util.boundary
import scala.util.boundary.break
object Day17 extends Solver(17):
case class Machine(var code: IndexedSeq[Long]):
def execute(
registers: Map[Char, Long],
output: Option[Int] = None
): Vector[Long] =
val reg = Array.from(registers).sorted.map(_._2)
var pc = 0
def combo(i: Long): Long =
i match
case i if i <= 3 => i
case i if i > 3 && i <= 6 => reg(i.toInt - 4)
var out = Vector.empty[Long]
boundary:
while pc < code.length do
code(pc) match
case 0 => reg(0) >>= combo(code(pc + 1)); pc += 2
case 1 => reg(1) ^= code(pc + 1); pc += 2
case 2 => reg(1) = combo(code(pc + 1)) % 8; pc += 2
case 3 => if reg(0) != 0 then pc = code(pc + 1).toInt else pc += 2
case 4 => reg(1) = reg(1) ^ reg(2); pc += 2
case 5 =>
out :+= combo(code(pc + 1)) % 8;
if output.exists(_ >= out.length) then break()
pc += 2
case 6 => reg(1) = reg(0) >> combo(code(pc + 1)); pc += 2
case 7 => reg(2) = reg(0) >> combo(code(pc + 1)); pc += 2
out
def part1(machine: Machine, initialRegs: Map[Char, Long]): String =
machine.execute(initialRegs).mkString(",")
def part2(machine: Machine, initialRegs: Map[Char, Long]): Long =
val target = machine.code.reverse
def rec(pos: Int = 0, acc: Long = 0): Option[Long] =
if pos >= target.length then return Some(acc)
def check(aVal: Long): Boolean =
machine.execute(initialRegs.updated('A', aVal), Some(1)).head == target(
pos
)
(0 until 8)
.map((acc << 3) + _)
.filter(check)
.flatMap(rec(pos + 1, _))
.headOption
rec().get
override def run(input: os.ReadablePath): (Timings, Solution) =
val Array(initial_, code_) = os.read(input).split("\n\n")
val initialRegs = initial_.linesIterator
.map(line => {
val spl = line.split(" ");
(spl(1)(0) -> spl(2).toLong)
})
.toMap
val code = longs(code_)
val machine = Machine(code)
val (p1_time, p1_solution) = timed { part1(machine, initialRegs) }
val (p2_time, p2_solution) = timed { part2(machine, initialRegs) }
(
Timings(0, p1_time, p2_time),
Solution(p1_solution, Long.box(p2_solution))
)

2
data/17.ans Normal file
View File

@@ -0,0 +1,2 @@
2,0,7,3,0,3,1,3,7
247839539763386

5
data/17.in Normal file
View File

@@ -0,0 +1,5 @@
Register A: 18427963
Register B: 0
Register C: 0
Program: 2,4,1,1,7,5,0,3,4,3,1,6,5,5,3,0