Skip to content

Instantly share code, notes, and snippets.

@atopuzov
Created December 19, 2016 00:37
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 atopuzov/914575e1b794a6e3723423d7d6e040b1 to your computer and use it in GitHub Desktop.
Save atopuzov/914575e1b794a6e3723423d7d6e040b1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import re
cpy_regex = re.compile(r"cpy ((?P<reg>[a-z]+)|(?P<num>\d+)) (?P<y>\w+)")
inc_regex = re.compile(r"inc (?P<x>\w+)")
dec_regex = re.compile(r"dec (?P<x>\w+)")
jnz_regex = re.compile(r"jnz ((?P<reg>[a-z]+)|(?P<num>\d+)) (?P<y>[\w-]+)")
class Cmd(object):
pass
class Cpy(Cmd):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Cpy<{}, {}>".format(self.x, self.y)
class CpyReg(Cpy):
def __repr__(self):
return "CpyReg<{}, {}>".format(self.x, self.y)
def execute(self, cpu):
cpu.set_register(self.y, cpu.get_register(self.x))
cpu.pc += 1
class CpyInt(Cpy):
def __repr__(self):
return "CpyInt<{}, {}>".format(self.x, self.y)
def execute(self, cpu):
cpu.set_register(self.y, self.x)
cpu.pc += 1
class Inc(Cmd):
def __init__(self, x):
self.x = x
def __repr__(self):
return "Inc<{}>".format(self.x)
def execute(self, cpu):
cpu.set_register(self.x, cpu.get_register(self.x) + 1)
cpu.pc += 1
class Dec(Cmd):
def __init__(self, x):
self.x = x
def __repr__(self):
return "Dec<{}>".format(self.x)
def execute(self, cpu):
cpu.set_register(self.x, cpu.get_register(self.x) - 1)
cpu.pc += 1
class Jnz(Cmd):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Jnz<{}, {}>".format(self.x, self.y)
class JnzNum(Jnz):
def execute(self, cpu):
if self.x != 0:
cpu.pc += self.y
else:
cpu.pc += 1
class JnzReg(Jnz):
def execute(self, cpu):
if cpu.get_register(self.x) != 0:
cpu.pc += self.y
else:
cpu.pc += 1
class CPU(object):
def __init__(self):
self.registers = {
'a': 0,
'b': 0,
'c': 0,
'd': 0
}
self.memory = []
self.pc = 0
def load(self, instructions):
self.memory = instructions
def get_register(self, register):
return self.registers[register]
def set_register(self, register, value):
self.registers[register] = value
def run(self):
while True:
try:
instruction = self.memory[self.pc]
except IndexError:
break
instruction.execute(self)
def __repr__(self):
return "CPU<PC={}, {}>".format(
self.pc,
', '.join("{}={}".format(k, self.registers[k]) for k
in sorted(self.registers.iterkeys())))
def parse_line(line):
def cpy(reg, num, y):
if reg is not None:
return CpyReg(reg, y)
elif num is not None:
return CpyInt(int(num), y)
raise ValueError("Unknown")
def inc(x):
return Inc(x)
def dec(x):
return Dec(x)
def jnz(reg, num, y):
if reg is not None:
return JnzReg(reg, int(y))
elif num is not None:
return JnzNum(int(num), int(y))
raise ValueError("Unknown")
parsers = {
cpy_regex: cpy,
inc_regex: inc,
dec_regex: dec,
jnz_regex: jnz,
}
for regex, func in parsers.iteritems():
match = regex.match(line)
if match is not None:
return func(**match.groupdict())
def demo_input():
return [
"cpy 41 a",
"inc a",
"inc a",
"dec a",
"jnz a 2",
"dec a",
]
def get_input():
with open('input.txt') as f:
return f.readlines()
def main():
# instructions = map(parse_line, demo_input())
instructions = map(parse_line, get_input())
cpu = CPU()
cpu.load(instructions)
cpu.run()
print cpu
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment