mirror of
https://github.com/Xevion/advent-of-code.git
synced 2025-12-05 23:14:16 -06:00
day 5 part 1 & 2 rehaul study copy
This commit is contained in:
@@ -1,60 +1,114 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
PATH = os.path.join(sys.path[0], '..', 'input')
|
||||
memory = list(open(PATH, 'r').read().split(','))
|
||||
class IntCodeExit(Exception):
|
||||
pass
|
||||
|
||||
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']:
|
||||
pass
|
||||
return params
|
||||
class IntCodeStatus(Exception):
|
||||
def __init__(self, code):
|
||||
self.code = code
|
||||
return super().__init__(f"Status code '{self.code}' was raised by the Intcode Computer.")
|
||||
|
||||
inputs = [1]
|
||||
pos = 0
|
||||
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
|
||||
|
||||
while pos < len(memory) - 4:
|
||||
if len(memory[pos]) < 5:
|
||||
memory[pos] = ('0' * (5 - len(memory[pos]))) + memory[pos]
|
||||
opcode = memory[pos][-2:]
|
||||
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),
|
||||
}
|
||||
|
||||
type1 = memory[pos][-3]
|
||||
type2 = memory[pos][-4]
|
||||
type3 = memory[pos][-5]
|
||||
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)
|
||||
}
|
||||
|
||||
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}')
|
||||
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])
|
||||
Reference in New Issue
Block a user