advent/2020/day08.nim

75 lines
1.6 KiB
Nim
Raw Normal View History

2021-12-01 01:09:36 +00:00
import lib/[loader, util]
import std/[strutils, sugar]
type
OpCode = enum
acc, jmp, nop
ProgramLine = object
op: OpCode
arg: int
visited: bool
proc loadProgram(): seq[ProgramLine] =
for line in loadStrings(8):
[strOp, strArg] <- line.split()
let pl = ProgramLine(
op: parseEnum[OpCode](strOp),
arg: parseInt(strArg),
visited: false
)
result.add(pl)
proc partOne(prog: seq[ProgramLine]): (int, bool) =
var prog = prog # mutable copy
var pos: int
var accum: int
while pos < prog.len and not prog[pos].visited:
prog[pos].visited = true
let line = prog[pos]
case line.op
of acc:
accum += line.arg
of jmp:
pos += line.arg - 1
of nop:
discard
pos += 1
if pos == prog.len:
result = (accum, true)
else:
result = (accum, false)
proc partTwo(prog: seq[ProgramLine]): int =
var prog = prog
for i, line in prog:
let orig = line.op
case line.op
of acc:
discard
of jmp:
prog[i].op = nop
of nop:
prog[i].op = jmp
let (accum, finished) = partOne(prog)
if finished:
return accum
prog[i].op = orig
raise newException(ValueError, "Couldn't find a working variation.")
when isMainModule:
let program = loadProgram()
let (accum, finished) = partOne(program)
echo "One: ", accum
echo "Two: ", partTwo(program)