Skip to content

Instantly share code, notes, and snippets.

@joelburton
Last active September 16, 2021 10:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joelburton/6b00b69e36d61824e5a077ed346f9a8c to your computer and use it in GitHub Desktop.
Save joelburton/6b00b69e36d61824e5a077ed346f9a8c to your computer and use it in GitHub Desktop.
import java.io.File
/** Single instruction for state machine. */
data class Instruction(val opcode: String, val operand: Int)
/** Marker exception raised during state machine runs. */
class Answer(val result: Int) : Throwable()
val lines = File("8.txt")
.readLines()
.map { it.split(" ") }
.map { (opcode, operand) -> Instruction(opcode, operand.toInt()) }
/** Run state machine, throwing result when loop detected. */
fun toLoop(acc: Int = 0, ip: Int = 0, ipSeen: Set<Int> = setOf()) {
if (ip in ipSeen) throw Answer(acc)
val (opcode, operand) = lines[ip]
return when (opcode) {
"acc" -> toLoop(acc + operand, ip + 1, ipSeen + ip)
"jmp" -> toLoop(acc, ip + operand, ipSeen + ip)
"nop" -> toLoop(acc, ip + 1, ipSeen + ip)
else -> throw IllegalStateException()
}
}
/** Run state machine to after final line, throwing accum when we reach there.
*
* This can branch exactly one time: a single jmp/nop can be switched.
*/
fun toEnd(
acc: Int = 0,
ip: Int = 0,
ipSeen: Set<Int> = setOf(),
fixed: Boolean = false
) {
if (ip in ipSeen) return
if (ip > lines.lastIndex) throw Answer(acc)
val (opcode, operand) = lines[ip]
when (opcode) {
"acc" -> toEnd(acc + operand, ip + 1, ipSeen + ip, fixed)
"jmp" -> {
toEnd(acc, ip + operand, ipSeen + ip, fixed)
if (!fixed) toEnd(acc, ip + 1, ipSeen + ip, true)
}
"nop" -> {
toEnd(acc, ip + 1, ipSeen + ip, fixed)
if (!fixed) toEnd(acc, ip + operand, ipSeen + ip, true)
}
else -> throw IllegalStateException()
}
}
fun main() {
try { toLoop() } catch (exc: Answer) { println(exc.result) }
try { toEnd() } catch (exc: Answer) { println(exc.result) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment