day 5 part 1 & 2 rehaul study copy

This commit is contained in:
Xevion
2019-12-07 15:45:13 -06:00
parent 19b0838006
commit 944bad6c57
+106 -52
View File
@@ -1,60 +1,114 @@
import os import os
import sys import sys
PATH = os.path.join(sys.path[0], '..', 'input') class IntCodeExit(Exception):
memory = list(open(PATH, 'r').read().split(',')) pass
def getParams(pos, opcode, type1, type2, type3): class IntCodeStatus(Exception):
params = [] def __init__(self, code):
if opcode in ['03', '04']: self.code = code
params.append(memory[pos + 1]) return super().__init__(f"Status code '{self.code}' was raised by the Intcode Computer.")
# if type1 == '0':
# params[-1] = memory[int(params[-1])]
elif opcode in ['01', '02']:
params.append(memory[pos + 1])
if type1 == '0':
params[-1] = memory[int(params[-1])]
params.append(memory[pos + 2])
if type2 == '0':
params[-1] = memory[int(params[-1])]
params.append(memory[pos + 3])
# if type3 == '0':
# params[-1] = memory[int(params[-1])]
# print(memory[pos:pos+4])
elif opcode in ['99']:
pass
return params
inputs = [1] class IntcodeComputer(object):
pos = 0 def __init__(self, memory, _input=[], pointer=0, silent=True):
self.memory = memory
self._input = iter(_input)
self.pointer = pointer
self.silent = silent
while pos < len(memory) - 4: self.READ_MODES = {
if len(memory[pos]) < 5: 0: (self.point, self.point, self.point),
memory[pos] = ('0' * (5 - len(memory[pos]))) + memory[pos] 100: (self.point, self.point, self.value),
opcode = memory[pos][-2:] 10: (self.point, self.value, self.point),
110: (self.point, self.value, self.value),
1: (self.value, self.point, self.point),
101: (self.value, self.point, self.value),
11: (self.value, self.value, self.point),
111: (self.value, self.value, self.value),
}
type1 = memory[pos][-3] self.OP_CODES = {
type2 = memory[pos][-4] 1 : (self.op_add, 3),
type3 = memory[pos][-5] 2 : (self.op_multiply, 3),
3 : (self.op_input, 1),
4 : (self.op_print, 1),
5 : (self.op_jit, 2),
6 : (self.op_jif, 2),
7 : (self.op_lth, 3),
8 : (self.op_eq, 3),
99 : (self.op_exit, 0)
}
params = getParams(pos, opcode, type1, type2, type3) def hasNext(self):
if opcode == '01': return self.pointer < len(self.memory)
memory[int(params[2])] = str(int(params[0]) + int(params[1]))
pos += 4 def next(self):
elif opcode == '02': op, params, offset = self.read(self.pointer)
memory[int(params[2])] = str(int(params[0]) * int(params[1])) self.pointer += offset
pos += 4 op(*params)
elif opcode == '03':
memory[int(params[0])] = str(inputs.pop(0)) def run(self):
pos += 2 statuses = []
elif opcode == '04': while self.hasNext():
print(f'OUTPUT: {params[0]}') try:
pos += 2 self.next()
elif opcode == '99': except IntCodeStatus as s:
print('PROGRAM BREAK') statuses.append(s.code)
pos += 1 except IntCodeExit:
break return statuses[-1]
else:
print(f'Unknown Opcode "{opcode}"') def read(self, pointer):
break code = self.memory[pointer]
print(f'#{pos // 4} {type3}{type2}{type1}{opcode} {params}') readmodes, opcode = divmod(code, 100)
op, nargs = self.OP_CODES[opcode]
argument_functions = self.READ_MODES[readmodes][:nargs]
parameters = [f(ptr) for f, ptr in zip(argument_functions, range(pointer+1, pointer+4))]
return op, parameters, nargs + 1
def op_add(self, param1, param2, param3):
self.memory[param3] = self.memory[param1] + self.memory[param2]
def op_multiply(self, param1, param2, param3):
self.memory[param3] = self.memory[param1] * self.memory[param2]
def op_input(self, param1):
self.memory[param1] = next(self._input)
def op_print(self, param1):
if not self.silent:
print(self.memory[param1])
raise IntCodeStatus(self.memory[param1])
def op_exit(self):
raise IntCodeExit()
def op_jit(self, param1, param2):
if self.memory[param1] != 0:
self.pointer = self.memory[param2]
def op_jif(self, param1, param2):
if self.memory[param1] == 0:
self.pointer = self.memory[param2]
def op_lth(self, param1, param2, param3):
self.memory[param3] = 1 if self.memory[param1] < self.memory[param2] else 0
def op_eq(self, param1, param2, param3):
self.memory[param3] = 1 if self.memory[param1] == self.memory[param2] else 0
def value(self, location):
return location
def point(self, location):
ptr = self.memory[location]
return ptr
def day5(memory, _input, silent=True):
computer = IntcodeComputer(memory.copy(), _input=_input, silent=silent)
print(computer.run())
path = os.path.join(sys.path[0], '..', 'input')
data = list(map(int, open(path, 'r').read().split(',')))
day5(data, _input=[1])
day5(data, _input=[5])