This commit is contained in:
Stefan Harmuth 2021-11-27 19:46:55 +01:00
parent c4a455e366
commit fbffd6e4fd
4 changed files with 89 additions and 42 deletions

21
day09.py Normal file
View File

@ -0,0 +1,21 @@
from aoc import AOCDay
from typing import Any
import intcode
class Day(AOCDay):
test_solutions_p1 = []
test_solutions_p2 = []
def part1(self) -> Any:
comp = intcode.IntCode(self.getInputAsArraySplit(",", int))
comp.addInput(1)
comp.run()
return comp.getOutput()
def part2(self) -> Any:
comp = intcode.IntCode(self.getInputAsArraySplit(",", int))
comp.addInput(2)
comp.run()
return comp.getOutput()

1
inputs/input09 Normal file
View File

@ -0,0 +1 @@
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,3,0,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,1,344,1023,1101,0,0,1020,1101,0,481,1024,1102,1,1,1021,1101,0,24,1005,1101,0,29,1018,1102,39,1,1019,1102,313,1,1028,1102,1,35,1009,1101,28,0,1001,1101,26,0,1013,1101,0,351,1022,1101,564,0,1027,1102,1,32,1011,1101,23,0,1006,1102,1,25,1015,1101,21,0,1003,1101,0,31,1014,1101,33,0,1004,1102,37,1,1000,1102,476,1,1025,1101,22,0,1007,1102,30,1,1012,1102,1,27,1017,1102,1,34,1002,1101,38,0,1008,1102,1,36,1010,1102,1,20,1016,1102,567,1,1026,1102,1,304,1029,109,-6,2108,35,8,63,1005,63,201,1001,64,1,64,1106,0,203,4,187,1002,64,2,64,109,28,21101,40,0,-9,1008,1013,38,63,1005,63,227,1001,64,1,64,1105,1,229,4,209,1002,64,2,64,109,-2,1205,1,243,4,235,1105,1,247,1001,64,1,64,1002,64,2,64,109,-12,2102,1,-5,63,1008,63,24,63,1005,63,271,1001,64,1,64,1105,1,273,4,253,1002,64,2,64,109,8,2108,22,-9,63,1005,63,295,4,279,1001,64,1,64,1106,0,295,1002,64,2,64,109,17,2106,0,-5,4,301,1001,64,1,64,1106,0,313,1002,64,2,64,109,-21,21107,41,40,7,1005,1019,333,1001,64,1,64,1105,1,335,4,319,1002,64,2,64,109,1,2105,1,10,1001,64,1,64,1105,1,353,4,341,1002,64,2,64,109,10,1206,-3,371,4,359,1001,64,1,64,1105,1,371,1002,64,2,64,109,-5,21108,42,42,-7,1005,1011,393,4,377,1001,64,1,64,1105,1,393,1002,64,2,64,109,-8,2101,0,-4,63,1008,63,23,63,1005,63,415,4,399,1105,1,419,1001,64,1,64,1002,64,2,64,109,13,21102,43,1,-6,1008,1017,43,63,1005,63,441,4,425,1106,0,445,1001,64,1,64,1002,64,2,64,109,-21,1207,0,33,63,1005,63,465,1001,64,1,64,1106,0,467,4,451,1002,64,2,64,109,19,2105,1,3,4,473,1106,0,485,1001,64,1,64,1002,64,2,64,109,1,21101,44,0,-7,1008,1015,44,63,1005,63,511,4,491,1001,64,1,64,1106,0,511,1002,64,2,64,109,2,1206,-3,527,1001,64,1,64,1105,1,529,4,517,1002,64,2,64,109,-8,1201,-7,0,63,1008,63,35,63,1005,63,555,4,535,1001,64,1,64,1105,1,555,1002,64,2,64,109,1,2106,0,10,1105,1,573,4,561,1001,64,1,64,1002,64,2,64,109,4,21107,45,46,-7,1005,1014,591,4,579,1106,0,595,1001,64,1,64,1002,64,2,64,109,-12,1208,-6,21,63,1005,63,617,4,601,1001,64,1,64,1105,1,617,1002,64,2,64,109,-11,1208,6,31,63,1005,63,637,1001,64,1,64,1106,0,639,4,623,1002,64,2,64,109,16,2101,0,-7,63,1008,63,20,63,1005,63,659,1105,1,665,4,645,1001,64,1,64,1002,64,2,64,109,3,2102,1,-9,63,1008,63,38,63,1005,63,691,4,671,1001,64,1,64,1106,0,691,1002,64,2,64,109,4,1205,-1,703,1105,1,709,4,697,1001,64,1,64,1002,64,2,64,109,-14,21108,46,45,7,1005,1014,729,1001,64,1,64,1105,1,731,4,715,1002,64,2,64,109,7,21102,47,1,0,1008,1014,45,63,1005,63,755,1001,64,1,64,1106,0,757,4,737,1002,64,2,64,109,-12,2107,34,7,63,1005,63,775,4,763,1105,1,779,1001,64,1,64,1002,64,2,64,109,-5,1207,6,22,63,1005,63,797,4,785,1106,0,801,1001,64,1,64,1002,64,2,64,109,12,1202,0,1,63,1008,63,35,63,1005,63,827,4,807,1001,64,1,64,1105,1,827,1002,64,2,64,109,-5,1202,0,1,63,1008,63,36,63,1005,63,851,1001,64,1,64,1105,1,853,4,833,1002,64,2,64,109,-2,1201,4,0,63,1008,63,20,63,1005,63,873,1105,1,879,4,859,1001,64,1,64,1002,64,2,64,109,2,2107,22,-1,63,1005,63,899,1001,64,1,64,1106,0,901,4,885,4,64,99,21102,1,27,1,21101,0,915,0,1105,1,922,21201,1,53897,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,0,942,0,1106,0,922,21202,1,1,-1,21201,-2,-3,1,21101,0,957,0,1105,1,922,22201,1,-1,-2,1105,1,968,22102,1,-2,-2,109,-3,2105,1,0

1
inputs/test_input09_1_0 Normal file
View File

@ -0,0 +1 @@
104,1125899906842624,99

View File

@ -11,21 +11,40 @@ class IntCodeState(Enum):
class IntCode(threading.Thread):
def __init__(self, memory: List[int], mem_size: int = 0):
def __init__(self, memory: List[int]):
super().__init__()
self.instr_ptr = 0
self.memory = memory
self.input_queue = Queue()
self.output_queue = Queue()
self.state = IntCodeState.INITIALIZED
if len(self.memory) < mem_size:
self.memory.extend([0] * (mem_size - len(self.memory)))
self.relative_base = 0
def get_parameter_value(self, address: int, mode: int) -> int:
def getMemoryValue(self, address: int) -> int:
if address > len(self.memory) - 1:
self.memory.extend([0] * (address - len(self.memory) + 1))
return self.memory[address]
def setMemoryValue(self, address: int, value: int):
if address > len(self.memory) - 1:
self.memory.extend([0] * (address - len(self.memory) + 1))
self.memory[address] = value
def getParameterValue(self, address: int, mode: int = 0) -> int:
if mode == 0:
return self.memory[self.memory[address]]
return self.getMemoryValue(self.getMemoryValue(address))
elif mode == 1:
return self.memory[address]
return self.getMemoryValue(address)
elif mode == 2:
return self.getMemoryValue(self.relative_base + self.getMemoryValue(address))
def getTargetAddress(self, address: int, mode: int = 0) -> int:
if mode == 0:
return self.getMemoryValue(address)
elif mode == 2:
return self.getMemoryValue(address) + self.relative_base
def isRunning(self):
return self.state == IntCodeState.RUNNING
@ -54,54 +73,59 @@ class IntCode(threading.Thread):
def run(self):
self.state = IntCodeState.RUNNING
while not self.isHalted():
instr = self.memory[self.instr_ptr] % 100
p1_mode = self.memory[self.instr_ptr] // 100 % 10
p2_mode = self.memory[self.instr_ptr] // 1_000 % 10
# p3_mode = self.memory[self.instr_ptr] // 10_000 % 10
instr = self.getMemoryValue(self.instr_ptr)
op_code = instr % 100
p1_mode = instr // 100 % 10
p2_mode = instr // 1_000 % 10
p3_mode = instr // 10_000 % 10
if instr == 1: # add
param1 = self.get_parameter_value(self.instr_ptr + 1, p1_mode)
param2 = self.get_parameter_value(self.instr_ptr + 2, p2_mode)
target_addr = self.memory[self.instr_ptr + 3]
self.memory[target_addr] = param1 + param2
if op_code == 1: # add
param1 = self.getParameterValue(self.instr_ptr + 1, p1_mode)
param2 = self.getParameterValue(self.instr_ptr + 2, p2_mode)
target_addr = self.getTargetAddress(self.instr_ptr + 3, p3_mode)
self.setMemoryValue(target_addr, param1 + param2)
self.instr_ptr += 4
elif instr == 2: # multiply
param1 = self.get_parameter_value(self.instr_ptr + 1, p1_mode)
param2 = self.get_parameter_value(self.instr_ptr + 2, p2_mode)
target_addr = self.memory[self.instr_ptr + 3]
self.memory[target_addr] = param1 * param2
elif op_code == 2: # multiply
param1 = self.getParameterValue(self.instr_ptr + 1, p1_mode)
param2 = self.getParameterValue(self.instr_ptr + 2, p2_mode)
target_addr = self.getTargetAddress(self.instr_ptr + 3, p3_mode)
self.setMemoryValue(target_addr, param1 * param2)
self.instr_ptr += 4
elif instr == 3: # input
target_addr = self.memory[self.instr_ptr + 1]
self.memory[target_addr] = self.input_queue.get()
elif op_code == 3: # input
target_addr = self.getTargetAddress(self.instr_ptr + 1, p1_mode)
self.setMemoryValue(target_addr, self.input_queue.get())
self.input_queue.task_done()
self.instr_ptr += 2
elif instr == 4: # output
self.output_queue.put(self.get_parameter_value(self.instr_ptr + 1, p1_mode))
elif op_code == 4: # output
self.output_queue.put(self.getParameterValue(self.instr_ptr + 1, p1_mode))
self.instr_ptr += 2
elif instr == 5: # jump-if-true
if self.get_parameter_value(self.instr_ptr + 1, p1_mode) != 0:
self.instr_ptr = self.get_parameter_value(self.instr_ptr + 2, p2_mode)
elif op_code == 5: # jump-if-true
if self.getParameterValue(self.instr_ptr + 1, p1_mode) != 0:
self.instr_ptr = self.getParameterValue(self.instr_ptr + 2, p2_mode)
else:
self.instr_ptr += 3
elif instr == 6: # jump-if-false
if self.get_parameter_value(self.instr_ptr + 1, p1_mode) == 0:
self.instr_ptr = self.get_parameter_value(self.instr_ptr + 2, p2_mode)
elif op_code == 6: # jump-if-false
if self.getParameterValue(self.instr_ptr + 1, p1_mode) == 0:
self.instr_ptr = self.getParameterValue(self.instr_ptr + 2, p2_mode)
else:
self.instr_ptr += 3
elif instr == 7: # less than
param1 = self.get_parameter_value(self.instr_ptr + 1, p1_mode)
param2 = self.get_parameter_value(self.instr_ptr + 2, p2_mode)
target_addr = self.memory[self.instr_ptr + 3]
self.memory[target_addr] = param1 < param2
elif op_code == 7: # less than
param1 = self.getParameterValue(self.instr_ptr + 1, p1_mode)
param2 = self.getParameterValue(self.instr_ptr + 2, p2_mode)
target_addr = self.getTargetAddress(self.instr_ptr + 3, p3_mode)
self.setMemoryValue(target_addr, param1 < param2)
self.instr_ptr += 4
elif instr == 8: # equals
param1 = self.get_parameter_value(self.instr_ptr + 1, p1_mode)
param2 = self.get_parameter_value(self.instr_ptr + 2, p2_mode)
target_addr = self.memory[self.instr_ptr + 3]
self.memory[target_addr] = param1 == param2
elif op_code == 8: # equals
param1 = self.getParameterValue(self.instr_ptr + 1, p1_mode)
param2 = self.getParameterValue(self.instr_ptr + 2, p2_mode)
target_addr = self.getTargetAddress(self.instr_ptr + 3, p3_mode)
self.setMemoryValue(target_addr, param1 == param2)
self.instr_ptr += 4
elif instr == 99:
elif op_code == 9:
param1 = self.getParameterValue(self.instr_ptr + 1, p1_mode)
self.relative_base += param1
self.instr_ptr += 2
elif op_code == 99:
self.state = IntCodeState.HALTED
return
else: