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

View File

@@ -1,60 +1,114 @@
import os
import sys
PATH = os.path.join(sys.path[0], '..', 'input')
memory = list(open(PATH, 'r').read().split(','))
def getParams(pos, opcode, type1, type2, type3):
params = []
if opcode in ['03', '04']:
params.append(memory[pos + 1])
# 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']:
class IntCodeExit(Exception):
pass
return params
inputs = [1]
pos = 0
class IntCodeStatus(Exception):
def __init__(self, code):
self.code = code
return super().__init__(f"Status code '{self.code}' was raised by the Intcode Computer.")
while pos < len(memory) - 4:
if len(memory[pos]) < 5:
memory[pos] = ('0' * (5 - len(memory[pos]))) + memory[pos]
opcode = memory[pos][-2:]
class IntcodeComputer(object):
def __init__(self, memory, _input=[], pointer=0, silent=True):
self.memory = memory
self._input = iter(_input)
self.pointer = pointer
self.silent = silent
type1 = memory[pos][-3]
type2 = memory[pos][-4]
type3 = memory[pos][-5]
self.READ_MODES = {
0: (self.point, self.point, self.point),
100: (self.point, self.point, self.value),
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),
}
params = getParams(pos, opcode, type1, type2, type3)
if opcode == '01':
memory[int(params[2])] = str(int(params[0]) + int(params[1]))
pos += 4
elif opcode == '02':
memory[int(params[2])] = str(int(params[0]) * int(params[1]))
pos += 4
elif opcode == '03':
memory[int(params[0])] = str(inputs.pop(0))
pos += 2
elif opcode == '04':
print(f'OUTPUT: {params[0]}')
pos += 2
elif opcode == '99':
print('PROGRAM BREAK')
pos += 1
break
else:
print(f'Unknown Opcode "{opcode}"')
break
print(f'#{pos // 4} {type3}{type2}{type1}{opcode} {params}')
self.OP_CODES = {
1 : (self.op_add, 3),
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)
}
def hasNext(self):
return self.pointer < len(self.memory)
def next(self):
op, params, offset = self.read(self.pointer)
self.pointer += offset
op(*params)
def run(self):
statuses = []
while self.hasNext():
try:
self.next()
except IntCodeStatus as s:
statuses.append(s.code)
except IntCodeExit:
return statuses[-1]
def read(self, pointer):
code = self.memory[pointer]
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])