From 661d054f916fec29433d2236732bb75ca9672658 Mon Sep 17 00:00:00 2001 From: Arne Wischer Date: Fri, 13 Dec 2019 15:04:06 +0100 Subject: [PATCH] Refactored OpcodeComputer --- days/comp.py | 45 ++++++++++++++++++++++++++++----------------- days/day1.py | 1 + days/day2.py | 20 +++++++++----------- days/day5.py | 9 +++------ days/day7.py | 9 +++------ days/test_comp.py | 31 +++++++++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 40 deletions(-) create mode 100644 days/test_comp.py diff --git a/days/comp.py b/days/comp.py index 28cd7ff..a359669 100644 --- a/days/comp.py +++ b/days/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) diff --git a/days/day1.py b/days/day1.py index 6c1e8ce..12769e0 100644 --- a/days/day1.py +++ b/days/day1.py @@ -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 diff --git a/days/day2.py b/days/day2.py index 4655df0..f16d0c9 100644 --- a/days/day2.py +++ b/days/day2.py @@ -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) diff --git a/days/day5.py b/days/day5.py index a6e789e..53530c5 100644 --- a/days/day5.py +++ b/days/day5.py @@ -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) diff --git a/days/day7.py b/days/day7.py index 2ecbd3b..a0081fe 100644 --- a/days/day7.py +++ b/days/day7.py @@ -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 diff --git a/days/test_comp.py b/days/test_comp.py new file mode 100644 index 0000000..37e6f56 --- /dev/null +++ b/days/test_comp.py @@ -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()