Refactored OpcodeComputer

master
Arne Wischer 6 years ago
parent 5fc1676776
commit 661d054f91
  1. 45
      days/comp.py
  2. 1
      days/day1.py
  3. 20
      days/day2.py
  4. 9
      days/day5.py
  5. 9
      days/day7.py
  6. 31
      days/test_comp.py

@ -15,10 +15,16 @@ class OpcodeComputer():
"""
__last_result: int = 0
memory = []
__initial_mem: List[int] = []
memory: List[int] = []
def __init__(self, mem: List[int]) -> None:
self.memory = mem
def __init__(self, file: str = None, mem: str = '99') -> None:
inp = mem
if file:
with open(file) as fp:
inp = fp.readline()
self.__initial_mem = [int(k) for k in inp.split(',')]
self.memory = self.__initial_mem
def parse_param(self, pc: int, mem: List[int]) \
-> Tuple[int, int, int, int]:
@ -31,14 +37,14 @@ class OpcodeComputer():
Returns:
Tuple[int, int, int, int]: current opcode, parameter a, b and c
"""
i: str = str(mem[pc])
i: str = "{0:05d}".format(mem[pc])
a: int = 0
b: int = 0
c: int = 0
try:
a = mem[pc+1] if i[-3:-4:-1] == '1' else mem[mem[pc+1]]
b = mem[pc+2] if i[-4:-5:-1] == '1' else mem[mem[pc+2]]
c = mem[pc+3] if i[-5:-6:-1] == '1' else mem[mem[pc+3]]
a = pc+1 if i[2] == '1' else mem[pc+1]
b = pc+2 if i[1] == '1' else mem[pc+2]
c = pc+3 if i[0] == '1' else mem[pc+3]
except IndexError:
pass
return (int(i[-2:]), a, b, c)
@ -54,36 +60,41 @@ class OpcodeComputer():
int: Content in memory at position 0
"""
pc: int = 0
mem = list(self.memory)
cmd: int = mem[pc]
mem = self.memory
cmd: int = self.memory[pc]
while cmd != 99:
cmd, a, b, c = self.parse_param(pc, mem)
if cmd == 1:
mem[mem[pc+3]] = a + b
mem[c] = mem[a] + mem[b]
pc += 4
elif cmd == 2:
mem[mem[pc+3]] = a * b
mem[c] = mem[a] * mem[b]
pc += 4
elif cmd == 3:
mem[mem[pc+1]] = int(inp.pop(0))
mem[a] = int(inp.pop(0))
pc += 2
elif cmd == 4:
yield str(a)
yield str(mem[a])
pc += 2
elif cmd == 5:
pc = b if a != 0 else pc + 3
pc = mem[b] if mem[a] != 0 else pc + 3
elif cmd == 6:
pc = b if a == 0 else pc + 3
pc = mem[b] if mem[a] == 0 else pc + 3
elif cmd == 7:
mem[mem[pc+3]] = 1 if a < b else 0
mem[c] = 1 if mem[a] < mem[b] else 0
pc += 4
elif cmd == 8:
mem[mem[pc+3]] = 1 if a == b else 0
mem[c] = 1 if mem[a] == mem[b] else 0
pc += 4
else:
raise Exception(f'Unknown Opcode encountered: {cmd}')
cmd = mem[pc]
self.__last_result = mem[0]
def process_all(self) -> int:
list(self.process_op())
return self.__last_result
def reset(self):
self.memory = list(self.__initial_mem)

@ -17,6 +17,7 @@ class Day1(unittest.TestCase):
self.assertEqual(fuel, 3402609)
def test_day1b(self):
sumfuel = 0
with open(self.inputfile) as fp:
for _, line in enumerate(fp):
sumfuel = 0

@ -8,23 +8,21 @@ class Day2(unittest.TestCase):
inputfile = os.path.join(os.path.dirname(__file__), "input/day2_input")
def test_day2a(self):
with open(self.inputfile) as fp:
code: List[int] = [int(k) for k in fp.readline().split(',')]
code[1] = 12
code[2] = 2
self.assertEqual(OpcodeComputer(code).process_all(), 5098658)
comp = OpcodeComputer(self.inputfile)
comp.memory[1] = 12
comp.memory[2] = 2
self.assertEqual(comp.process_all(), 5098658)
def test_day2b(self):
with open(self.inputfile) as fp:
file_code: List[int] = [int(k) for k in fp.readline().split(',')]
comp = OpcodeComputer(self.inputfile)
a: int = 0
b: int = 0
for a, b in [(x, y) for x in range(100) for y in range(100)]:
code = list(file_code)
code[1] = a
code[2] = b
comp.reset()
comp.memory[1] = int(a)
comp.memory[2] = int(b)
result = OpcodeComputer(code).process_all()
result = comp.process_all()
if result == 19690720:
break
self.assertEqual(100 * a + b, 5064)

@ -4,19 +4,16 @@ from .comp import OpcodeComputer
class Day5(unittest.TestCase):
def get_code(self):
inputfile = os.path.join(os.path.dirname(__file__), "input/day5_input")
with open(inputfile) as fp:
return [int(k) for k in fp.readline().split(',')]
inputfile = os.path.join(os.path.dirname(__file__), "input/day5_input")
def test_day5a(self):
sut = OpcodeComputer(self.get_code())
sut = OpcodeComputer(self.inputfile)
outp = list(sut.process_op([1]))
self.assertEqual(int(outp[-1]), 8332629)
def test_day5b(self):
sut = OpcodeComputer(self.get_code())
sut = OpcodeComputer(self.inputfile)
outp = list(sut.process_op([5]))
self.assertEqual(int(outp[0]), 8805067)

@ -5,13 +5,10 @@ import itertools
class Day7(unittest.TestCase):
def get_code(self):
inputfile = os.path.join(os.path.dirname(__file__), "input/day7_input")
with open(inputfile) as fp:
return [int(k) for k in fp.readline().split(',')]
inputfile = os.path.join(os.path.dirname(__file__), "input/day7_input")
def test_day7a(self):
com = OpcodeComputer(self.get_code())
com = OpcodeComputer(self.inputfile)
configs = itertools.permutations(range(5), 5)
res: int = 0
@ -29,7 +26,7 @@ class Day7(unittest.TestCase):
https://www.reddit.com/r/adventofcode/comments/e7om28/2019_day_7_part_2_python3_help_with/fa3bh4w/
https://pastebin.com/cyLTHUYV
"""
com = OpcodeComputer(self.get_code())
com = OpcodeComputer(self.inputfile)
res: int = 0
for config in itertools.permutations(range(5, 10), 5):
sig: int = 0

@ -0,0 +1,31 @@
import unittest
import os
from .comp import OpcodeComputer
class Test_OpcodeComputer(unittest.TestCase):
inputfile = os.path.join(os.path.dirname(__file__), "input/day9_input")
def test_addition(self):
com = OpcodeComputer(mem="1,0,0,0,99")
com.process_all()
self.assertEqual(com.memory, [2, 0, 0, 0, 99])
def test_multiplication(self):
com = OpcodeComputer(mem="2,3,0,3,99")
com.process_all()
self.assertEqual(com.memory, [2, 3, 0, 6, 99])
def test_multiplication2(self):
com = OpcodeComputer(mem="2,4,4,5,99,0")
com.process_all()
self.assertEqual(com.memory, [2, 4, 4, 5, 99, 9801])
def test_addition2(self):
com = OpcodeComputer(mem="1,1,1,4,99,5,6,0,99")
com.process_all()
self.assertEqual(com.memory, [30, 1, 1, 4, 2, 5, 6, 0, 99])
if __name__ == "__main__":
unittest.main()
Loading…
Cancel
Save