day07, welcome back to threaded intcode computers \o/
This commit is contained in:
parent
8e397e4442
commit
e3a8fb64e6
14
day05.py
14
day05.py
@ -9,16 +9,18 @@ class Day(AOCDay):
|
||||
|
||||
def part1(self) -> Any:
|
||||
comp = IntCode(self.getInputAsArraySplit(",", int))
|
||||
comp.input.put(1)
|
||||
comp.run()
|
||||
comp.addInput(1)
|
||||
comp.start()
|
||||
while True:
|
||||
if (check := comp.output.get()) != 0:
|
||||
if (check := comp.getOutput()) != 0:
|
||||
comp.join()
|
||||
return check
|
||||
|
||||
def part2(self) -> Any:
|
||||
comp = IntCode(self.getInputAsArraySplit(",", int))
|
||||
comp.input.put(5)
|
||||
comp.run()
|
||||
comp.addInput(5)
|
||||
comp.start()
|
||||
while True:
|
||||
if (check := comp.output.get()) != 0:
|
||||
if (check := comp.getOutput()) != 0:
|
||||
comp.join()
|
||||
return check
|
||||
|
||||
72
day07.py
Normal file
72
day07.py
Normal file
@ -0,0 +1,72 @@
|
||||
import itertools
|
||||
|
||||
from aoc import AOCDay
|
||||
|
||||
from intcode import IntCode
|
||||
from typing import Any, List
|
||||
|
||||
|
||||
def get_comps(memory: List[int]) -> List[IntCode]:
|
||||
comps = []
|
||||
for _ in range(5):
|
||||
comps.append(IntCode(memory.copy()))
|
||||
|
||||
return comps
|
||||
|
||||
|
||||
class Day(AOCDay):
|
||||
test_solutions_p1 = [43210, 54321, 65210]
|
||||
test_solutions_p2 = [139629729, 18216]
|
||||
|
||||
def part1(self) -> Any:
|
||||
init_memory = self.getInputAsArraySplit(",", int)
|
||||
max_signal = 0
|
||||
phase_settings = [0, 1, 2, 3, 4]
|
||||
for s in itertools.permutations(phase_settings):
|
||||
comps = get_comps(init_memory)
|
||||
for i, input1 in enumerate(s):
|
||||
if i == 0:
|
||||
input2 = 0
|
||||
else:
|
||||
input2 = comps[i-1].getOutput()
|
||||
|
||||
comps[i].addInput(input1)
|
||||
comps[i].addInput(input2)
|
||||
comps[i].run()
|
||||
|
||||
signal = comps[4].getOutput()
|
||||
if signal > max_signal:
|
||||
max_signal = signal
|
||||
|
||||
return max_signal
|
||||
|
||||
def part2(self) -> Any:
|
||||
init_memory = self.getInputAsArraySplit(",", int)
|
||||
max_signal = 0
|
||||
phase_settings = [5, 6, 7, 8, 9]
|
||||
for s in itertools.permutations(phase_settings):
|
||||
comps = get_comps(init_memory.copy())
|
||||
|
||||
for i, input1 in enumerate(s):
|
||||
if i == 0 and not comps[i].isRunning():
|
||||
input2 = 0
|
||||
else:
|
||||
input2 = comps[i-1].getOutput()
|
||||
|
||||
comps[i].addInput(input1)
|
||||
comps[i].addInput(input2)
|
||||
comps[i].start()
|
||||
|
||||
while not comps[4].isHalted():
|
||||
for i in range(5):
|
||||
if not comps[i].isHalted() and not comps[i-1].isHalted():
|
||||
comps[i].addInput(comps[i-1].getOutput())
|
||||
|
||||
signal = comps[4].getOutput()
|
||||
if signal > max_signal:
|
||||
max_signal = signal
|
||||
|
||||
for i in range(5):
|
||||
comps[i].join()
|
||||
|
||||
return max_signal
|
||||
1
inputs/input07
Normal file
1
inputs/input07
Normal file
@ -0,0 +1 @@
|
||||
3,8,1001,8,10,8,105,1,0,0,21,38,59,76,89,106,187,268,349,430,99999,3,9,1002,9,3,9,101,2,9,9,1002,9,4,9,4,9,99,3,9,1001,9,5,9,1002,9,5,9,1001,9,2,9,1002,9,3,9,4,9,99,3,9,1001,9,4,9,102,4,9,9,1001,9,3,9,4,9,99,3,9,101,4,9,9,1002,9,5,9,4,9,99,3,9,1002,9,3,9,101,5,9,9,1002,9,3,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,99
|
||||
1
inputs/test_input07_1_0
Normal file
1
inputs/test_input07_1_0
Normal file
@ -0,0 +1 @@
|
||||
3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0
|
||||
1
inputs/test_input07_1_1
Normal file
1
inputs/test_input07_1_1
Normal file
@ -0,0 +1 @@
|
||||
3,23,3,24,1002,24,10,24,1002,23,-1,23,101,5,23,23,1,24,23,23,4,23,99,0,0
|
||||
1
inputs/test_input07_1_2
Normal file
1
inputs/test_input07_1_2
Normal file
@ -0,0 +1 @@
|
||||
3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0
|
||||
1
inputs/test_input07_2_0
Normal file
1
inputs/test_input07_2_0
Normal file
@ -0,0 +1 @@
|
||||
3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5
|
||||
1
inputs/test_input07_2_1
Normal file
1
inputs/test_input07_2_1
Normal file
@ -0,0 +1 @@
|
||||
3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10
|
||||
56
intcode.py
56
intcode.py
@ -1,14 +1,23 @@
|
||||
from typing import List
|
||||
from enum import Enum
|
||||
from queue import Queue
|
||||
import threading
|
||||
from typing import List, Union
|
||||
|
||||
|
||||
class IntCode:
|
||||
class IntCodeState(Enum):
|
||||
INITIALIZED = 0
|
||||
RUNNING = 1
|
||||
HALTED = 2
|
||||
|
||||
|
||||
class IntCode(threading.Thread):
|
||||
def __init__(self, memory: List[int], mem_size: int = 0):
|
||||
super().__init__()
|
||||
self.instr_ptr = 0
|
||||
self.halted = False
|
||||
self.memory = memory
|
||||
self.input = Queue()
|
||||
self.output = Queue()
|
||||
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)))
|
||||
|
||||
@ -18,8 +27,33 @@ class IntCode:
|
||||
elif mode == 1:
|
||||
return self.memory[address]
|
||||
|
||||
def isRunning(self):
|
||||
return self.state == IntCodeState.RUNNING
|
||||
|
||||
def isHalted(self):
|
||||
return self.state == IntCodeState.HALTED
|
||||
|
||||
def sendOutputTo(self, target_queue: Queue):
|
||||
self.output_queue = target_queue
|
||||
|
||||
def addInput(self, value: int):
|
||||
self.input_queue.put(value)
|
||||
|
||||
def getOutput(self, count: int = 1, block: bool = True, timeout: int = None) -> Union[int, List[int]]:
|
||||
if count == 1:
|
||||
res = self.output_queue.get(block=block, timeout=timeout)
|
||||
self.output_queue.task_done()
|
||||
else:
|
||||
res = []
|
||||
for _ in range(count):
|
||||
res.append(self.output_queue.get(block=block, timeout=timeout))
|
||||
self.output_queue.task_done()
|
||||
|
||||
return res
|
||||
|
||||
def run(self):
|
||||
while not self.halted:
|
||||
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
|
||||
@ -38,11 +72,12 @@ class IntCode:
|
||||
self.memory[target_addr] = param1 * param2
|
||||
self.instr_ptr += 4
|
||||
elif instr == 3: # input
|
||||
target_addr = self.memory[self.instr_ptr + 3]
|
||||
self.memory[target_addr] = self.input.get()
|
||||
target_addr = self.memory[self.instr_ptr + 1]
|
||||
self.memory[target_addr] = self.input_queue.get()
|
||||
self.input_queue.task_done()
|
||||
self.instr_ptr += 2
|
||||
elif instr == 4: # output
|
||||
self.output.put(self.get_parameter_value(self.instr_ptr + 1, p1_mode))
|
||||
self.output_queue.put(self.get_parameter_value(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:
|
||||
@ -67,6 +102,7 @@ class IntCode:
|
||||
self.memory[target_addr] = param1 == param2
|
||||
self.instr_ptr += 4
|
||||
elif instr == 99:
|
||||
self.halted = True
|
||||
self.state = IntCodeState.HALTED
|
||||
return
|
||||
else:
|
||||
raise ValueError("Invalid instruction encountered at pos %d: %d" % (self.instr_ptr, instr))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user