-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDay08HandheldHalting.kt
More file actions
78 lines (65 loc) · 2.47 KB
/
Copy pathDay08HandheldHalting.kt
File metadata and controls
78 lines (65 loc) · 2.47 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package adventofcode.year2020
import adventofcode.Puzzle
import adventofcode.PuzzleInput
import adventofcode.year2020.Day08HandheldHalting.Companion.Operation.ACC
import adventofcode.year2020.Day08HandheldHalting.Companion.Operation.JMP
import adventofcode.year2020.Day08HandheldHalting.Companion.Operation.NOP
class Day08HandheldHalting(
customInput: PuzzleInput? = null,
) : Puzzle(customInput) {
private val instructions by lazy { input.lines().map(::Instruction) }
override fun partOne() = instructions.execute().acc
override fun partTwo() =
(instructions.indices)
.mapNotNull {
val before = instructions.take(it)
val after = instructions.takeLast(instructions.size - it - 1)
when (instructions[it].operation) {
ACC -> null
JMP -> before + Instruction(NOP, instructions[it].argument) + after
NOP -> before + Instruction(JMP, instructions[it].argument) + after
}
}.map { it.execute() }
.first { it.terminatedNormally }
.acc
companion object {
private data class Instruction(
val operation: Operation,
val argument: Int,
) {
constructor(input: String) : this(Operation(input.split(" ").first()), input.split(" ").last().toInt())
}
private fun List<Instruction>.execute(): ExecutionResult {
var acc = 0
var index = 0
val visitedInstructions = mutableListOf<Int>()
while (index < size && !visitedInstructions.contains(index)) {
visitedInstructions.add(index)
when (this[index].operation) {
ACC -> {
acc += this[index].argument
index++
}
JMP -> index += this[index].argument
NOP -> index++
}
}
return ExecutionResult(acc, index == size)
}
private data class ExecutionResult(
val acc: Int,
val terminatedNormally: Boolean,
)
private enum class Operation(
val type: String,
) {
ACC("acc"),
JMP("jmp"),
NOP("nop"),
;
companion object {
operator fun invoke(type: String) = entries.associateBy(Operation::type)[type]!!
}
}
}
}