In [1]:
from collections import defaultdict
In [2]:
class Assembunny:
def __init__(self):
self.registers = defaultdict(int)
self.pointer = 0
def _add_to_register(self, register, value):
self.registers[register] = value
def copy(self, register, value):
try:
value = int(value)
except ValueError:
value = self.registers[value]
self._add_to_register(register, value)
def increase(self, register):
self.registers[register] += 1
def decrease(self, register):
self.registers[register] -= 1
@staticmethod
def is_number(n):
try:
n = int(n)
except ValueError:
return False
return True
def jump(self, index, register=None):
if register is not None and (self.registers[register] != 0 or
self.is_number(register)):
self.pointer += index
else:
self.pointer += 1
def execute(self, instructions):
while True:
try:
instruction = instructions[self.pointer]
instruction = instruction.split()
if instruction[0] == 'cpy':
self.copy(instruction[-1], instruction[1])
self.jump(1)
elif instruction[0] == 'inc':
self.increase(instruction[-1])
self.jump(1)
elif instruction[0] == 'dec':
self.decrease(instruction[-1])
self.jump(1)
else:
self.jump(int(instruction[-1]), instruction[1])
except IndexError:
return self.registers
In [3]:
# Test
data = [
'cpy 41 a', # set register a to 41,
'inc a', # increase its value by 1, (42)
'inc a', # increase its value by 1, (43)
'dec a', # decrease its value by 1, (42)
'jnz a 2', # skip the last dec a
'dec a'
]
assembunny = Assembunny()
assert(assembunny.execute(data)['a'] == 42)
In [4]:
data = [line.strip() for line in open('data/day_12.txt', 'r')]
In [5]:
%%time
assembunny = Assembunny()
res = assembunny.execute(data)
In [6]:
res
Out[6]:
In [7]:
%%time
assembunny = Assembunny()
assembunny.increase('c')
res = assembunny.execute(data)
In [8]:
res
Out[8]: