Skip to content

Commit 7994405

Browse files
committed
Solution 2018-16, part 1 (Chronal Classification)
1 parent 0158ea8 commit 7994405

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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+
)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package de.ronny_h.aoc.year2018.day16
2+
3+
import de.ronny_h.aoc.extensions.asList
4+
import io.kotest.core.spec.style.StringSpec
5+
import io.kotest.matchers.shouldBe
6+
7+
class ChronalClassificationTest : StringSpec({
8+
9+
val input = """
10+
Before: [3, 2, 1, 1]
11+
9 2 1 2
12+
After: [3, 2, 2, 1]
13+
14+
Before: [3, 2, 1, 1]
15+
9 2 1 2
16+
After: [3, 2, 2, 1]
17+
18+
19+
20+
7 3 2 0
21+
7 2 1 1
22+
7 1 0 3
23+
8 1 0 1
24+
""".asList()
25+
26+
"input can be parsed" {
27+
input.parseCPUSamples() shouldBe listOf(
28+
CPUSample(listOf(3, 2, 1, 1), 9, 2, 1, 2, listOf(3, 2, 2, 1)),
29+
CPUSample(listOf(3, 2, 1, 1), 9, 2, 1, 2, listOf(3, 2, 2, 1)),
30+
)
31+
}
32+
33+
"the given sample behaves like three opcodes" {
34+
WristDevice().behaveLikeNumberOfOpcodes(
35+
listOf(
36+
CPUSample(listOf(3, 2, 1, 1), 9, 2, 1, 2, listOf(3, 2, 2, 1))
37+
)
38+
) shouldBe listOf(3)
39+
}
40+
41+
"part 1: both of the given samples behave like three opcodes" {
42+
ChronalClassification().part1(input) shouldBe 2
43+
}
44+
45+
"part 2" {
46+
val input = listOf("")
47+
ChronalClassification().part2(input) shouldBe 0
48+
}
49+
})

0 commit comments

Comments
 (0)