|
| 1 | +package de.ronny_h.aoc.year2018.day16 |
| 2 | + |
| 3 | +import de.ronny_h.aoc.AdventOfCode |
| 4 | +import de.ronny_h.aoc.extensions.collections.split |
| 5 | + |
| 6 | +fun main() = ChronalClassification().run(531, 0) |
| 7 | + |
| 8 | +class ChronalClassification : AdventOfCode<Int>(2018, 16) { |
| 9 | + override fun part1(input: List<String>): Int { |
| 10 | + val samples = input.parseCPUSamples() |
| 11 | + val device = WristDevice() |
| 12 | + return device.behaveLikeNumberOfOpcodes(samples).filter { it > 2 }.size |
| 13 | + } |
| 14 | + |
| 15 | + override fun part2(input: List<String>): Int { |
| 16 | + return 0 |
| 17 | + } |
| 18 | +} |
| 19 | + |
| 20 | +class WristDevice { |
| 21 | + private val registers = mutableListOf(0, 0, 0, 0) |
| 22 | + |
| 23 | + private val addr = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 24 | + registers[outC] = registers[inA] + registers[inB] |
| 25 | + } |
| 26 | + |
| 27 | + private val addi = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 28 | + registers[outC] = registers[inA] + inB |
| 29 | + } |
| 30 | + |
| 31 | + private val mulr = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 32 | + registers[outC] = registers[inA] * registers[inB] |
| 33 | + } |
| 34 | + |
| 35 | + private val muli = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 36 | + registers[outC] = registers[inA] * inB |
| 37 | + } |
| 38 | + |
| 39 | + private val banr = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 40 | + registers[outC] = registers[inA] and registers[inB] |
| 41 | + } |
| 42 | + |
| 43 | + private val bani = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 44 | + registers[outC] = registers[inA] and inB |
| 45 | + } |
| 46 | + |
| 47 | + private val borr = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 48 | + registers[outC] = registers[inA] or registers[inB] |
| 49 | + } |
| 50 | + |
| 51 | + private val bori = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 52 | + registers[outC] = registers[inA] or inB |
| 53 | + } |
| 54 | + |
| 55 | + private val setr = { inA: Int, _: Int, outC: Int, registers: MutableList<Int> -> |
| 56 | + registers[outC] = registers[inA] |
| 57 | + } |
| 58 | + |
| 59 | + private val seti = { inA: Int, _: Int, outC: Int, registers: MutableList<Int> -> |
| 60 | + registers[outC] = inA |
| 61 | + } |
| 62 | + |
| 63 | + private val gtir = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 64 | + registers[outC] = if (inA > registers[inB]) 1 else 0 |
| 65 | + } |
| 66 | + |
| 67 | + private val gtri = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 68 | + registers[outC] = if (registers[inA] > inB) 1 else 0 |
| 69 | + } |
| 70 | + |
| 71 | + private val gtrr = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 72 | + registers[outC] = if (registers[inA] > registers[inB]) 1 else 0 |
| 73 | + } |
| 74 | + |
| 75 | + private val eqir = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 76 | + registers[outC] = if (inA == registers[inB]) 1 else 0 |
| 77 | + } |
| 78 | + |
| 79 | + private val eqri = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 80 | + registers[outC] = if (registers[inA] == inB) 1 else 0 |
| 81 | + } |
| 82 | + |
| 83 | + private val eqrr = { inA: Int, inB: Int, outC: Int, registers: MutableList<Int> -> |
| 84 | + registers[outC] = if (registers[inA] == registers[inB]) 1 else 0 |
| 85 | + } |
| 86 | + |
| 87 | + private val operations = |
| 88 | + listOf(addr, addi, mulr, muli, banr, bani, borr, bori, setr, seti, gtir, gtri, gtrr, eqir, eqri, eqrr) |
| 89 | + |
| 90 | + fun behaveLikeNumberOfOpcodes(samples: List<CPUSample>) = |
| 91 | + samples.map { sample -> |
| 92 | + operations.count { op -> |
| 93 | + val registers = sample.registersBefore.toMutableList() |
| 94 | + op(sample.a, sample.b, sample.c, registers) |
| 95 | + registers == sample.registersAfter |
| 96 | + } |
| 97 | + } |
| 98 | +} |
| 99 | + |
| 100 | +fun List<String>.parseCPUSamples(): List<CPUSample> { |
| 101 | + return buildList { |
| 102 | + for (block in split()) { |
| 103 | + if (!block.first().startsWith("Before")) { |
| 104 | + break |
| 105 | + } |
| 106 | + val registersBefore = block[0].parseRegister("Before: ") |
| 107 | + val operation = block[1].split(" ").map(String::toInt) |
| 108 | + val registersAfter = block[2].parseRegister("After: ") |
| 109 | + add(CPUSample(registersBefore, operation[0], operation[1], operation[2], operation[3], registersAfter)) |
| 110 | + } |
| 111 | + } |
| 112 | +} |
| 113 | + |
| 114 | +private fun String.parseRegister(prefix: String) = |
| 115 | + substringAfter("$prefix[").substringBefore("]").split(", ").map(String::toInt) |
| 116 | + |
| 117 | +data class CPUSample( |
| 118 | + val registersBefore: List<Int>, |
| 119 | + val opcode: Int, |
| 120 | + val a: Int, |
| 121 | + val b: Int, |
| 122 | + val c: Int, |
| 123 | + val registersAfter: List<Int> |
| 124 | +) |
0 commit comments