You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.6 KiB
89 lines
2.6 KiB
from typing import List, Tuple, Iterator
|
|
|
|
|
|
class OpcodeComputer():
|
|
"""OpcodeCOmputer for Advent of Code 2019
|
|
|
|
OpcodeComputer as specified by day 2 and 5 of the Advent of \
|
|
Code 2019 challenge.
|
|
|
|
.. _Advent of Code 2019 day 2
|
|
https://adventofcode.com/2019/day/2
|
|
|
|
.. _Advent of Code 2019 day 5
|
|
https://adventofcode.com/2019/day/5
|
|
|
|
"""
|
|
__last_result: int = 0
|
|
memory = []
|
|
|
|
def __init__(self, mem: List[int]) -> None:
|
|
self.memory = mem
|
|
|
|
def parse_param(self, pc: int, mem: List[int]) \
|
|
-> Tuple[int, int, int, int]:
|
|
"""Parse Intcode and return parameters as specified by parameter mode
|
|
|
|
Args:
|
|
pc (int): current instruction pointer
|
|
mem (List[int]): program code
|
|
|
|
Returns:
|
|
Tuple[int, int, int, int]: current opcode, parameter a, b and c
|
|
"""
|
|
i: str = str(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]]
|
|
except IndexError:
|
|
pass
|
|
return (int(i[-2:]), a, b, c)
|
|
|
|
def process_op(self, inp: List[int] = [])\
|
|
-> Iterator[str]:
|
|
"""Run program code
|
|
|
|
Args:
|
|
mem (List[int]): Memory to run OpcodeComputer on
|
|
|
|
Returns:
|
|
int: Content in memory at position 0
|
|
"""
|
|
pc: int = 0
|
|
mem = list(self.memory)
|
|
cmd: int = mem[pc]
|
|
|
|
while cmd != 99:
|
|
cmd, a, b, c = self.parse_param(pc, mem)
|
|
if cmd == 1:
|
|
mem[mem[pc+3]] = a + b
|
|
pc += 4
|
|
elif cmd == 2:
|
|
mem[mem[pc+3]] = a * b
|
|
pc += 4
|
|
elif cmd == 3:
|
|
mem[mem[pc+1]] = int(inp.pop(0))
|
|
pc += 2
|
|
elif cmd == 4:
|
|
yield str(a)
|
|
pc += 2
|
|
elif cmd == 5:
|
|
pc = b if a != 0 else pc + 3
|
|
elif cmd == 6:
|
|
pc = b if a == 0 else pc + 3
|
|
elif cmd == 7:
|
|
mem[mem[pc+3]] = 1 if a < b else 0
|
|
pc += 4
|
|
elif cmd == 8:
|
|
mem[mem[pc+3]] = 1 if a == b else 0
|
|
pc += 4
|
|
cmd = mem[pc]
|
|
self.__last_result = mem[0]
|
|
|
|
def process_all(self) -> int:
|
|
list(self.process_op())
|
|
return self.__last_result
|
|
|