diff --git a/src/main/kotlin/com/basdado/adventofcode/Day19.kt b/src/main/kotlin/com/basdado/adventofcode/Day19.kt new file mode 100644 index 0000000..44d6879 --- /dev/null +++ b/src/main/kotlin/com/basdado/adventofcode/Day19.kt @@ -0,0 +1,106 @@ +package com.basdado.adventofcode + +import java.util.Arrays.stream +import java.util.stream.Collectors + +const val DAY19_INPUT = "/day/19/input.txt" + +fun main() { + + val day = Day19() + day.puzzle1() + day.puzzle2() +} + +class Day19 { + + fun puzzle1() { + val (ip, instructions) = parseInput() + + val regsBeforeExecution = IntArray(6) { 0 } + val regsAfterExecution = executeProgram(regsBeforeExecution, ip, instructions) + println(regsAfterExecution.joinToString(" ")) + } + + fun puzzle2() { + val (ip, instructions) = parseInput() + + val regsBeforeExecution = IntArray(6) { if (it == 0) 1 else 0 } + val regsAfterExecution = executeProgram(regsBeforeExecution, ip, instructions) + println(regsAfterExecution.joinToString(" ")) + } + + private fun executeProgram(regsBefore: IntArray, ip: Int, instructions: List): IntArray { + + val regs = regsBefore.clone() + var i = 0L + while (true) { + if (regs[ip] !in 0 until instructions.size) { + break + } + instructions[regs[ip]].execute(regs) + // Instruction pointer is incremented + regs[ip]++ + if (i % 1000000L == 0L) { + println(regs.joinToString(" ") + "...") + } + i++ + } + return regs + } + + private fun parseInput(): Pair> { + val ipRegex = Regex("""#ip (\d+)""") + val ip = + lines(DAY19_INPUT).findFirst().map { ipRegex.matchEntire(it) }.map { it!!.groupValues[1].toInt() }.get() + + val instructionRegex = Regex("""([a-z]{4}) (\d+) (\d+) (\d+)""") + val instructions = lines(DAY19_INPUT) + .map { instructionRegex.matchEntire(it) } + .filter { it != null }.map { it!! } + .map { + Instruction( + opcode(it.groupValues[1]), + it.groupValues[2].toInt(), + it.groupValues[3].toInt(), + it.groupValues[4].toInt() + ) + } + .collect(Collectors.toList()) + return Pair(ip, instructions) + } + + data class Instruction(val opcode: Opcode, val a: Int, val b: Int, val c: Int) { + fun execute(regs: IntArray) { + opcode.operation.invoke(regs, a,b,c) + } + } + + fun opcode(id: String): Opcode = stream(Opcode.values()).filter { it.id == id }.findFirst().get() + + enum class Opcode(val id: String, val operation: (IntArray, Int, Int, Int) -> Unit) { + + ADDR("addr", {regs, a, b, c -> regs[c] = regs[a] + regs[b]}), + ADDI("addi", {regs, a, b, c -> regs[c] = regs[a] + b}), + + MULR("mulr", {regs, a, b, c -> regs[c] = regs[a] * regs[b]}), + MULI("muli", {regs, a, b, c -> regs[c] = regs[a] * b}), + + BANR("banr", {regs, a, b, c -> regs[c] = regs[a] and regs[b]}), + BANI("bani", {regs, a, b, c -> regs[c] = regs[a] and b}), + + BORR("borr", {regs, a, b, c -> regs[c] = regs[a] or regs[b]}), + BORI("bori", {regs, a, b, c -> regs[c] = regs[a] or b}), + + SETR("setr", {regs, a, b, c -> regs[c] = regs[a]}), + SETI("seti", {regs, a, b, c -> regs[c] = a}), + + GTIR("gtir", {regs, a, b, c -> regs[c] = if (a > regs[b]) 1 else 0}), + GTRI("gtri", {regs, a, b, c -> regs[c] = if (regs[a] > b) 1 else 0}), + GTRR("gtrr", {regs, a, b, c -> regs[c] = if (regs[a] > regs[b]) 1 else 0}), + + EQIR("eqir", {regs, a, b, c -> regs[c] = if (a == regs[b]) 1 else 0}), + EQRI("eqri", {regs, a, b, c -> regs[c] = if (regs[a] == b) 1 else 0}), + EQRR("eqrr", {regs, a, b, c -> regs[c] = if (regs[a] == regs[b]) 1 else 0}), + } +} \ No newline at end of file diff --git a/src/main/resources/day/15/input_maarten.txt b/src/main/resources/day/15/input_maarten.txt new file mode 100644 index 0000000..736d6b1 --- /dev/null +++ b/src/main/resources/day/15/input_maarten.txt @@ -0,0 +1,32 @@ +################################ +####################.......##### +##################.G.......###.# +##################...G.........# +#############................### +############..............###### +############...##......######### +############...G.....#.######### +##..##........G##.........###### +##..##.....#.G...........E#..### +##..##.....#.....G......G..E..## +##G............................# +#....G........#####..G.........# +#......#.G...#######..E.......## +#...##..G...#########E.....##### +##...G.#....#########.....###### +######G.G...#########..#.####### +######.#...G#########.########## +#####.......#########.########## +#####.GE.....#######..########## +#####.....E...#####...########## +#######....G..........########## +#######..........G..############ +######.G............############ +#########...........#..######### +############..........########## +############E...E.##...######### +#############.....E..E.######### +##############.........######### +##############...#....########## +###############..#.############# +################################ \ No newline at end of file diff --git a/src/main/resources/day/19/example.txt b/src/main/resources/day/19/example.txt new file mode 100644 index 0000000..f159f7e --- /dev/null +++ b/src/main/resources/day/19/example.txt @@ -0,0 +1,8 @@ +#ip 0 +seti 5 0 1 +seti 6 0 2 +addi 0 1 0 +addr 1 2 3 +setr 1 0 0 +seti 8 0 4 +seti 9 0 5 \ No newline at end of file diff --git a/src/main/resources/day/19/input.txt b/src/main/resources/day/19/input.txt new file mode 100644 index 0000000..f5c8d13 --- /dev/null +++ b/src/main/resources/day/19/input.txt @@ -0,0 +1,37 @@ +#ip 4 +addi 4 16 4 +seti 1 9 5 +seti 1 5 2 +mulr 5 2 1 +eqrr 1 3 1 +addr 1 4 4 +addi 4 1 4 +addr 5 0 0 +addi 2 1 2 +gtrr 2 3 1 +addr 4 1 4 +seti 2 6 4 +addi 5 1 5 +gtrr 5 3 1 +addr 1 4 4 +seti 1 2 4 +mulr 4 4 4 +addi 3 2 3 +mulr 3 3 3 +mulr 4 3 3 +muli 3 11 3 +addi 1 5 1 +mulr 1 4 1 +addi 1 2 1 +addr 3 1 3 +addr 4 0 4 +seti 0 2 4 +setr 4 8 1 +mulr 1 4 1 +addr 4 1 1 +mulr 4 1 1 +muli 1 14 1 +mulr 1 4 1 +addr 3 1 3 +seti 0 0 0 +seti 0 2 4 \ No newline at end of file