-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day8.kt
61 lines (52 loc) · 2.28 KB
/
Day8.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package day08
import util.readFile
class Day8(inputFile: String) {
private val lines: List<String> = readFile(inputFile)
fun part1(): Int = lines.toInstructions().execute().first
fun part2(): Int {
val initialInstructions = lines.toInstructions()
val initialResult = initialInstructions.execute()
initialResult.third
.filter { it.first.isJumpOrNop() }
.reversed()
.forEach { item ->
val instruction = item.first
val instructions = initialInstructions.toMutableList()
instructions[instruction.line] = instruction.toggled()
val result = instructions.executeFrom(instruction.line, item.second, initialResult.third)
if(result.second >= instructions.size) {
return result.first
}
}
error("failed to find way out of program")
}
fun List<Instruction>.execute() = executeFrom(0, 0, mutableListOf())
fun List<Instruction>.executeFrom(startIndex: Int, startValue: Int, history: MutableList<Pair<Instruction, Int>>): Triple<Int, Int, MutableList<Pair<Instruction, Int>>> {
var index = startIndex
var value = startValue
while(index < this.size && !history.any { it.first === this[index]}) {
history += Pair(this[index], value)
when(this[index].operation) {
"nop" -> index++
"acc" -> value += this[index++].argument
"jmp" -> index += this[index].argument
}
}
return Triple(value, index, history)
}
}
data class Instruction(val line: Int, val operation: String, val argument: Int) {
fun toggled(): Instruction = Instruction(
this.line,
when(this.operation) {
"jmp" -> "nop"
"nop" -> "jmp"
else -> error("blah")
}, this.argument
)
fun isJumpOrNop() = this.operation in listOf("jmp", "nop")
}
fun Iterable<String>.toInstructions(): List<Instruction> = this.mapIndexed { index, line ->
val(operation, argumentStr) = """^([a-z]+) ([+\-]\d+)${'$'}""".toRegex().matchEntire(line)!!.destructured
Instruction(index, operation, argumentStr.toInt())
}