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.start()
pos = Coordinate(0, 0)
return discover(comp, Grid(), pos)
grid = discover(comp, Grid(), pos)
comp.stop()
return grid
def part1(self) -> Any:
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)
count = 0
grid.print(true_char='#', false_char=' ', mark=[Coordinate(0, 0), OXYGEN_POS])
while queue:
print("step", count, "=>", queue)
count += 1
next_queue = deque()
for pos in queue:

View File

@ -1,6 +1,6 @@
import threading
from collections import defaultdict
from queue import Queue
from queue import Queue, Empty
from enum import Enum
from typing import List
@ -9,13 +9,7 @@ class IntCodeState(Enum):
INITIALIZED = 0
RUNNING = 1
HALTED = 2
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)]
STOPPED = 3
class IntCode(threading.Thread):
@ -34,8 +28,6 @@ class IntCode(threading.Thread):
return int(self.memory[address])
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
def getParameterValue(self, address: int, mode: int = 0) -> int:
@ -58,6 +50,21 @@ class IntCode(threading.Thread):
def isHalted(self):
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):
self.input_queue.put(value)
@ -67,15 +74,18 @@ class IntCode(threading.Thread):
def hasOutput(self):
return self.output_queue.qsize() > 0
def getOutput(self, count: int = 1, timeout: int = 10) -> int | List[int] | None:
return _get_from_queue(self.output_queue, count, timeout)
def getOutput(self, count: int = 1, timeout: int = 3) -> int | List[int] | None:
return self._get_from_queue(self.output_queue, count, timeout)
def getInput(self, count: int = 1, timeout: int = 10) -> int | List[int] | None:
return _get_from_queue(self.input_queue, count, timeout)
def getInput(self, count: int = 1, timeout: int = 3) -> int | List[int] | None:
return self._get_from_queue(self.input_queue, count, timeout)
def stop(self):
self.state = IntCodeState.STOPPED
def run(self):
self.state = IntCodeState.RUNNING
while not self.isHalted():
while not self.isHalted() and not self.isStopped():
instr = self.getMemoryValue(self.instr_ptr)
op_code = instr % 100
p1_mode = instr // 100 % 10