cleanly stop still running background intcode computers

This commit is contained in:
Stefan Harmuth 2022-12-10 14:47:50 +01:00
parent 556d0205b8
commit 19acd22c9b
2 changed files with 28 additions and 19 deletions

View File

@ -51,7 +51,9 @@ class Day(AOCDay):
comp = IntCode(self.getInputAsArraySplit(",", int)) comp = IntCode(self.getInputAsArraySplit(",", int))
comp.start() comp.start()
pos = Coordinate(0, 0) pos = Coordinate(0, 0)
return discover(comp, Grid(), pos) grid = discover(comp, Grid(), pos)
comp.stop()
return grid
def part1(self) -> Any: def part1(self) -> Any:
return len(self.get_grid().getPath(Coordinate(0, 0), OXYGEN_POS, includeDiagonal=False, walls=[True])) - 1 return len(self.get_grid().getPath(Coordinate(0, 0), OXYGEN_POS, includeDiagonal=False, walls=[True])) - 1
@ -63,10 +65,7 @@ class Day(AOCDay):
grid.set(OXYGEN_POS, 2) grid.set(OXYGEN_POS, 2)
count = 0 count = 0
grid.print(true_char='#', false_char=' ', mark=[Coordinate(0, 0), OXYGEN_POS])
while queue: while queue:
print("step", count, "=>", queue)
count += 1 count += 1
next_queue = deque() next_queue = deque()
for pos in queue: for pos in queue:

View File

@ -1,6 +1,6 @@
import threading import threading
from collections import defaultdict from collections import defaultdict
from queue import Queue from queue import Queue, Empty
from enum import Enum from enum import Enum
from typing import List from typing import List
@ -9,13 +9,7 @@ class IntCodeState(Enum):
INITIALIZED = 0 INITIALIZED = 0
RUNNING = 1 RUNNING = 1
HALTED = 2 HALTED = 2
STOPPED = 3
def _get_from_queue(queue: Queue, count: int = 1, timeout: int = 10) -> int | List[int] | None:
if count == 1:
return queue.get(timeout=timeout)
else:
return [queue.get(timeout=timeout) for _ in range(count)]
class IntCode(threading.Thread): class IntCode(threading.Thread):
@ -34,8 +28,6 @@ class IntCode(threading.Thread):
return int(self.memory[address]) return int(self.memory[address])
def setMemoryValue(self, address: int, value: int): def setMemoryValue(self, address: int, value: int):
if not isinstance(value, int):
print("Something set", value, "at", address, "and that's not int, but", value.__class__.__name__)
self.memory[address] = value self.memory[address] = value
def getParameterValue(self, address: int, mode: int = 0) -> int: def getParameterValue(self, address: int, mode: int = 0) -> int:
@ -58,6 +50,21 @@ class IntCode(threading.Thread):
def isHalted(self): def isHalted(self):
return self.state == IntCodeState.HALTED return self.state == IntCodeState.HALTED
def isStopped(self):
return self.state == IntCodeState.STOPPED
def _get_from_queue(self, queue: Queue, count: int = 1, timeout: int = 3) -> int | List[int] | None:
try:
if count == 1:
return queue.get(timeout=timeout)
else:
return [queue.get(timeout=timeout) for _ in range(count)]
except Empty as e:
if self.state == IntCodeState.STOPPED:
return None
else:
raise e
def addInput(self, value: int): def addInput(self, value: int):
self.input_queue.put(value) self.input_queue.put(value)
@ -67,15 +74,18 @@ class IntCode(threading.Thread):
def hasOutput(self): def hasOutput(self):
return self.output_queue.qsize() > 0 return self.output_queue.qsize() > 0
def getOutput(self, count: int = 1, timeout: int = 10) -> int | List[int] | None: def getOutput(self, count: int = 1, timeout: int = 3) -> int | List[int] | None:
return _get_from_queue(self.output_queue, count, timeout) return self._get_from_queue(self.output_queue, count, timeout)
def getInput(self, count: int = 1, timeout: int = 10) -> int | List[int] | None: def getInput(self, count: int = 1, timeout: int = 3) -> int | List[int] | None:
return _get_from_queue(self.input_queue, count, timeout) return self._get_from_queue(self.input_queue, count, timeout)
def stop(self):
self.state = IntCodeState.STOPPED
def run(self): def run(self):
self.state = IntCodeState.RUNNING self.state = IntCodeState.RUNNING
while not self.isHalted(): while not self.isHalted() and not self.isStopped():
instr = self.getMemoryValue(self.instr_ptr) instr = self.getMemoryValue(self.instr_ptr)
op_code = instr % 100 op_code = instr % 100
p1_mode = instr // 100 % 10 p1_mode = instr // 100 % 10