better intcode queueing

This commit is contained in:
Stefan Harmuth 2022-12-10 13:03:30 +01:00
parent f63a3623d4
commit 2f9d621879

View File

@ -1,6 +1,6 @@
import threading import threading
import time from collections import defaultdict
from collections import deque, defaultdict from queue import Queue
from enum import Enum from enum import Enum
from typing import List from typing import List
@ -11,17 +11,11 @@ class IntCodeState(Enum):
HALTED = 2 HALTED = 2
def _get_from_queue(queue: deque, count: int = 1, timeout: int = 10) -> int | List[int] | None: def _get_from_queue(queue: Queue, count: int = 1, timeout: int = 10) -> int | List[int] | None:
started = time.perf_counter()
while len(queue) < count:
time.sleep(0.0001)
if time.perf_counter() - started > timeout:
raise TimeoutError()
if count == 1: if count == 1:
return queue.popleft() return queue.get(timeout=timeout)
else: else:
return [queue.popleft() for _ in range(count)] return [queue.get(timeout=timeout) for _ in range(count)]
class IntCode(threading.Thread): class IntCode(threading.Thread):
@ -31,8 +25,8 @@ class IntCode(threading.Thread):
self.memory = defaultdict(int) self.memory = defaultdict(int)
for i, v in enumerate(memory): for i, v in enumerate(memory):
self.memory[i] = v self.memory[i] = v
self.input_queue = deque() self.input_queue = Queue()
self.output_queue = deque() self.output_queue = Queue()
self.state = IntCodeState.INITIALIZED self.state = IntCodeState.INITIALIZED
self.relative_base = 0 self.relative_base = 0
@ -62,14 +56,14 @@ class IntCode(threading.Thread):
def isHalted(self): def isHalted(self):
return self.state == IntCodeState.HALTED return self.state == IntCodeState.HALTED
def sendOutputTo(self, target_queue: deque):
self.output_queue = target_queue
def addInput(self, value: int): def addInput(self, value: int):
self.input_queue.append(value) self.input_queue.put(value)
def addOutput(self, value: int):
self.output_queue.put(value)
def hasOutput(self): def hasOutput(self):
return len(self.output_queue) > 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 = 10) -> int | List[int] | None:
return _get_from_queue(self.output_queue, count, timeout) return _get_from_queue(self.output_queue, count, timeout)
@ -103,7 +97,7 @@ class IntCode(threading.Thread):
self.setMemoryValue(target_addr, self.getInput()) self.setMemoryValue(target_addr, self.getInput())
self.instr_ptr += 2 self.instr_ptr += 2
elif op_code == 4: # output elif op_code == 4: # output
self.output_queue.append(self.getParameterValue(self.instr_ptr + 1, p1_mode)) self.addOutput(self.getParameterValue(self.instr_ptr + 1, p1_mode))
self.instr_ptr += 2 self.instr_ptr += 2
elif op_code == 5: # jump-if-true elif op_code == 5: # jump-if-true
if self.getParameterValue(self.instr_ptr + 1, p1_mode) != 0: if self.getParameterValue(self.instr_ptr + 1, p1_mode) != 0: