65 lines
1.5 KiB
Python
65 lines
1.5 KiB
Python
|
#!/usr/bin/env python3
|
||
|
from functools import reduce
|
||
|
import numpy as np
|
||
|
import re, sys
|
||
|
import sys
|
||
|
|
||
|
def lst(l): # get nice mutable tuple from line
|
||
|
ins, num = l.split() # space separated fields
|
||
|
num = int(num) if num[0] == '-' else int(num[1:])
|
||
|
return [ins, num]
|
||
|
|
||
|
def nxt(acc, ip, ins, num, size):
|
||
|
size += 1 # NO LOOP AROUND THIS TIME
|
||
|
if ins == 'nop':
|
||
|
return acc, (ip + 1) % size
|
||
|
elif ins == 'acc':
|
||
|
return acc + num, (ip + 1) % size
|
||
|
elif ins == 'jmp':
|
||
|
return acc, (ip + num) % size
|
||
|
else:
|
||
|
return 'fish'
|
||
|
|
||
|
def repmachine(lines):
|
||
|
acc = ip = prev = 0
|
||
|
done = [False for i in range(len(lines))]
|
||
|
while True:
|
||
|
if done[ip]:
|
||
|
return prev
|
||
|
done[ip] = True
|
||
|
prev = acc
|
||
|
acc, ip = nxt(acc, ip, *lines[ip], len(lines))
|
||
|
|
||
|
def machine(lines):
|
||
|
acc = ip = 0
|
||
|
done = [False for i in range(len(lines))]
|
||
|
while True:
|
||
|
if ip == len(lines):
|
||
|
return acc
|
||
|
if done[ip]:
|
||
|
return None
|
||
|
done[ip] = True
|
||
|
acc, ip = nxt(acc, ip, *lines[ip], len(lines))
|
||
|
|
||
|
def fix(ins):
|
||
|
if ins == 'jmp':
|
||
|
return 'nop'
|
||
|
if ins == 'nop':
|
||
|
return 'jmp'
|
||
|
return ins
|
||
|
|
||
|
fn = sys.argv[1] if len(sys.argv) > 1 else 'input8'
|
||
|
with open(fn) as f:
|
||
|
|
||
|
lines = [lst(l.strip()) for l in f.readlines()]
|
||
|
|
||
|
print(repmachine(lines))
|
||
|
|
||
|
for i, l in enumerate(lines):
|
||
|
svi = l[0]
|
||
|
l[0] = fix(l[0])
|
||
|
if machine(lines):
|
||
|
print(machine(lines))
|
||
|
exit()
|
||
|
l[0] = svi
|