Day 17.
This commit is contained in:
parent
76c01e01e5
commit
b0e4461a7d
123
src/aoc2024/Day17.kt
Normal file
123
src/aoc2024/Day17.kt
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
package aoc2024
|
||||||
|
|
||||||
|
import println
|
||||||
|
import readInput
|
||||||
|
import splitInts
|
||||||
|
|
||||||
|
/*
|
||||||
|
--- Day 17: Chronospatial Computer ---
|
||||||
|
https://adventofcode.com/2024/day/17
|
||||||
|
*/
|
||||||
|
fun main() {
|
||||||
|
|
||||||
|
val inlineTestInput = """
|
||||||
|
Register A: 117440
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 0,3,5,4,3,0
|
||||||
|
"""
|
||||||
|
val regs = LongArray(3)
|
||||||
|
|
||||||
|
fun getComboOperand(op: Int): Long =
|
||||||
|
when (op) {
|
||||||
|
0, 1, 2, 3 -> op.toLong()
|
||||||
|
4, 5, 6 -> regs[op - 4]
|
||||||
|
else -> throw IllegalStateException()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun part1(input: List<String>): String {
|
||||||
|
regs[0] = input[0].split(" ")[2].toLong()
|
||||||
|
regs[1] = input[1].split(" ")[2].toLong()
|
||||||
|
regs[2] = input[2].split(" ")[2].toLong()
|
||||||
|
val ops = input[4].split(" ")[1].splitInts(",")
|
||||||
|
val outs = ArrayList<Int>()
|
||||||
|
var pc = 0
|
||||||
|
while (pc < ops.size) {
|
||||||
|
when (ops[pc++]) {
|
||||||
|
// adv
|
||||||
|
0 -> regs[0] = regs[0] shr getComboOperand(ops[pc++]).toInt()
|
||||||
|
// bdv
|
||||||
|
6 -> regs[1] = regs[0] shr getComboOperand(ops[pc++]).toInt()
|
||||||
|
// cdv
|
||||||
|
7 -> regs[2] = regs[0] shr getComboOperand(ops[pc++]).toInt()
|
||||||
|
// bxl
|
||||||
|
1 -> regs[1] = regs[1] xor ops[pc++].toLong()
|
||||||
|
// bst
|
||||||
|
2 -> regs[1] = getComboOperand(ops[pc++]) and 7
|
||||||
|
// jnz
|
||||||
|
3 -> if (regs[0] == 0L) pc++ else pc = ops[pc]
|
||||||
|
// bxc
|
||||||
|
4 -> {
|
||||||
|
regs[1] = regs[1] xor regs[2]
|
||||||
|
pc++
|
||||||
|
}
|
||||||
|
// out
|
||||||
|
5 -> outs.add((getComboOperand(ops[pc++]) and 7).toInt())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outs.joinToString(",")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun verify(rega: Long, ops: List<Int>, outs: List<Int>): Boolean {
|
||||||
|
regs[0] = rega
|
||||||
|
var pc = 0
|
||||||
|
var outpos = 0
|
||||||
|
while (pc < ops.size) {
|
||||||
|
when (ops[pc++]) {
|
||||||
|
// adv
|
||||||
|
0 -> regs[0] = regs[0] shr getComboOperand(ops[pc++]).toInt()
|
||||||
|
// bdv
|
||||||
|
6 -> regs[1] = regs[0] shr getComboOperand(ops[pc++]).toInt()
|
||||||
|
// cdv
|
||||||
|
7 -> regs[2] = regs[0] shr getComboOperand(ops[pc++]).toInt()
|
||||||
|
// bxl
|
||||||
|
1 -> regs[1] = regs[1] xor ops[pc++].toLong()
|
||||||
|
// bst
|
||||||
|
2 -> regs[1] = getComboOperand(ops[pc++]) and 7
|
||||||
|
// jnz
|
||||||
|
3 -> if (regs[0] == 0L) pc++ else pc = ops[pc]
|
||||||
|
// bxc
|
||||||
|
4 -> {
|
||||||
|
regs[1] = regs[1] xor regs[2]
|
||||||
|
pc++
|
||||||
|
}
|
||||||
|
// out
|
||||||
|
5 -> {
|
||||||
|
val o = (getComboOperand(ops[pc++]) and 7).toInt()
|
||||||
|
if (outs[outpos++] != o) return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun rec(a: Long, p: Int, ops: List<Int>, outs: List<Int>): Long {
|
||||||
|
val partOutput = outs.take(p).reversed()
|
||||||
|
// assuming that all programs use 3 bit shifts in the last operation
|
||||||
|
for (i in 0L..7L) {
|
||||||
|
if (verify((a shl 3) or i, ops, partOutput)) {
|
||||||
|
if (p == outs.size) return (a shl 3) or i
|
||||||
|
val res = rec((a shl 3) or i, p + 1, ops, outs)
|
||||||
|
if (res != 0L) return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun part2(input: List<String>): Long {
|
||||||
|
val ops = input[4].split(" ")[1].splitInts(",")
|
||||||
|
val outs = ops.reversed()
|
||||||
|
return rec(0L, 1, ops, outs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test if implementation meets criteria from the description, like:
|
||||||
|
val testInput = inlineTestInput.trim().reader().readLines()
|
||||||
|
//val testInput = readInput("aoc2024/Day17_test")
|
||||||
|
val testInputPart1Result = part1(testInput)
|
||||||
|
println("Part 1 Test: $testInputPart1Result")
|
||||||
|
|
||||||
|
val input = readInput("aoc2024/Day17")
|
||||||
|
part1(input).println()
|
||||||
|
part2(input).println()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user