Skip to content

Commit a016593

Browse files
committed
Solution 2017-25 (The Halting Problem)
1 parent e07c745 commit a016593

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package de.ronny_h.aoc.year2017.day25
2+
3+
import de.ronny_h.aoc.AdventOfCode
4+
import de.ronny_h.aoc.extensions.collections.split
5+
import de.ronny_h.aoc.year2017.day25.TapeDirection.LEFT
6+
import de.ronny_h.aoc.year2017.day25.TapeDirection.RIGHT
7+
8+
fun main() = TheHaltingProblem().run(2794, 0)
9+
10+
class TheHaltingProblem : AdventOfCode<Int>(2017, 25) {
11+
override fun part1(input: List<String>): Int = TuringMachine(input.parseTuringMachineConfiguration()).run()
12+
override fun part2(input: List<String>): Int = 0
13+
}
14+
15+
fun List<String>.parseTuringMachineConfiguration(): TuringMachineConfiguration {
16+
val startState = first().substringAfter("Begin in state ").substringBefore(".")
17+
val checkAfter = this[1].substringAfter("Perform a diagnostic checksum after ").split(" ").first().toInt()
18+
19+
val rules = subList(3, size).split().flatMap { rule ->
20+
val inState = rule[0].substringAfter("In state ").trim(':')
21+
listOf(rule.parseRule(inState, 1), rule.parseRule(inState, 5))
22+
}
23+
24+
return TuringMachineConfiguration(startState, checkAfter, rules)
25+
}
26+
27+
private fun List<String>.parseRule(
28+
inState: String,
29+
offset: Int,
30+
): Rule {
31+
val value = this[offset].substringAfter(" If the current value is ").trim(':').toByte()
32+
val toWrite = this[offset + 1].substringAfter(" - Write the value ").trim('.').toByte()
33+
val toMove = if (this[offset + 2].endsWith("right.")) RIGHT else LEFT
34+
val nextState = this[offset + 3].substringAfter(" - Continue with state ").trim('.')
35+
return Rule(inState, value, toWrite, toMove, nextState)
36+
}
37+
38+
data class TuringMachineConfiguration(val startState: String, val checkAfter: Int, val rules: List<Rule>)
39+
40+
data class Rule(
41+
val inState: String,
42+
val value: Byte,
43+
val toWrite: Byte,
44+
val toMove: TapeDirection,
45+
val nextState: String,
46+
)
47+
48+
enum class TapeDirection(val offset: Int) {
49+
LEFT(-1), RIGHT(1)
50+
}
51+
52+
class TuringMachine(private val configuration: TuringMachineConfiguration) {
53+
private val tape = mutableMapOf<Int, Byte>().withDefault { 0 }
54+
private var cursor = 0
55+
private var state = configuration.startState
56+
57+
private val rules = configuration.rules.associateBy { Pair(it.inState, it.value) }
58+
59+
fun run(): Int {
60+
repeat(configuration.checkAfter) {
61+
val rule = rules.getValue(Pair(state, tape.getValue(cursor)))
62+
tape[cursor] = rule.toWrite
63+
cursor += rule.toMove.offset
64+
state = rule.nextState
65+
}
66+
return tape.values.count { it == 1.toByte() }
67+
}
68+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package de.ronny_h.aoc.year2017.day25
2+
3+
import de.ronny_h.aoc.extensions.asList
4+
import de.ronny_h.aoc.year2017.day25.TapeDirection.LEFT
5+
import de.ronny_h.aoc.year2017.day25.TapeDirection.RIGHT
6+
import io.kotest.core.spec.style.StringSpec
7+
import io.kotest.matchers.shouldBe
8+
9+
class TheHaltingProblemTest : StringSpec({
10+
11+
val input = """
12+
Begin in state A.
13+
Perform a diagnostic checksum after 6 steps.
14+
15+
In state A:
16+
If the current value is 0:
17+
- Write the value 1.
18+
- Move one slot to the right.
19+
- Continue with state B.
20+
If the current value is 1:
21+
- Write the value 0.
22+
- Move one slot to the left.
23+
- Continue with state B.
24+
25+
In state B:
26+
If the current value is 0:
27+
- Write the value 1.
28+
- Move one slot to the left.
29+
- Continue with state A.
30+
If the current value is 1:
31+
- Write the value 1.
32+
- Move one slot to the right.
33+
- Continue with state A.
34+
""".asList()
35+
36+
"input can be parsed" {
37+
input.parseTuringMachineConfiguration() shouldBe TuringMachineConfiguration(
38+
"A", 6, listOf(
39+
Rule("A", 0, 1, RIGHT, "B"),
40+
Rule("A", 1, 0, LEFT, "B"),
41+
Rule("B", 0, 1, LEFT, "A"),
42+
Rule("B", 1, 1, RIGHT, "A"),
43+
)
44+
)
45+
}
46+
47+
"part 1: the diagnostic checksum after running the blueprint" {
48+
TheHaltingProblem().part1(input) shouldBe 3
49+
}
50+
51+
"part 2 does nothing" {
52+
TheHaltingProblem().part2(input) shouldBe 0
53+
}
54+
})

0 commit comments

Comments
 (0)