From 700e3fdf30411ac4d2c6ce54351c8747875c8238 Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Sat, 3 Dec 2022 11:47:08 +0100 Subject: [PATCH] day18 --- day18.py | 114 +++++++++++++++++++++++++++++++++++++++++++ inputs/input18 | 41 ++++++++++++++++ inputs/input18_test | 10 ++++ inputs/input18_test2 | 7 +++ 4 files changed, 172 insertions(+) create mode 100644 day18.py create mode 100644 inputs/input18 create mode 100644 inputs/input18_test create mode 100644 inputs/input18_test2 diff --git a/day18.py b/day18.py new file mode 100644 index 0000000..c8a369a --- /dev/null +++ b/day18.py @@ -0,0 +1,114 @@ +import time +from collections import defaultdict +from threading import Thread +from tools.aoc import AOCDay +from typing import Any +from queue import Queue + + +class Duet(Thread): + def __init__(self, commands: list, pid: int = 0, input_queue: Queue = None, export_queue: Queue = None) -> None: + super().__init__() + self.commands = commands + self.pid = pid + self.input_queue = input_queue + self.export_queue = export_queue + self.state = 0 + self.output = 0 + + def run(self) -> None: + last_freq = 0 + register = defaultdict(int) + register['p'] = self.pid + index = 0 + while 0 <= index < len(self.commands): + cmd = self.commands[index] + + if len(cmd) == 3: + value_index = 2 + else: + value_index = 1 + + try: + value = int(cmd[value_index]) + except ValueError: + value = register[cmd[value_index]] + + match cmd[0]: + case "snd": + last_freq = value + if self.export_queue is not None: + self.export_queue.put(value) + self.output += 1 + case "set": + register[cmd[1]] = value + case "add": + register[cmd[1]] += value + case "mul": + register[cmd[1]] *= value + case "mod": + register[cmd[1]] %= value + case "rcv": + if self.input_queue is not None: + self.state = 1 + while self.input_queue.empty(): + time.sleep(0.01) + register[cmd[1]] = self.input_queue.get() + self.state = 0 + else: + if register[cmd[1]] != 0: + self.output = last_freq + return + case "jgz": + try: + if int(cmd[1]) > 0: + index += value - 1 + except ValueError: + if register[cmd[1]] > 0: + index += value - 1 + case _: + raise ValueError("Unknown command: " + cmd[0]) + + index += 1 + + return + + +class Day(AOCDay): + inputs = [ + [ + (4, "input18_test"), + (7071, "input18") + ], + [ + (3, "input18_test2"), + (8001, "input18") + ] + ] + + def part1(self) -> Any: + duet = Duet([x.split(" ") for x in self.getInput()]) + duet.start() + duet.join() + return duet.output + + def part2(self) -> Any: + q1, q2 = Queue(), Queue() + p1 = Duet([x.split(" ") for x in self.getInput()], 0, q1, q2) + p2 = Duet([x.split(" ") for x in self.getInput()], 1, q2, q1) + p1.daemon = True + p2.daemon = True + p1.start() + p2.start() + + while p1.is_alive() or p2.is_alive(): + if (p1.state == 1 and q1.empty()) and (p2.state == 1 and q2.empty()): + return p2.output + time.sleep(0.01) + + return p2.output + + +if __name__ == '__main__': + day = Day(2017, 18) + day.run(verbose=True) diff --git a/inputs/input18 b/inputs/input18 new file mode 100644 index 0000000..ea1762c --- /dev/null +++ b/inputs/input18 @@ -0,0 +1,41 @@ +set i 31 +set a 1 +mul p 17 +jgz p p +mul a 2 +add i -1 +jgz i -2 +add a -1 +set i 127 +set p 826 +mul p 8505 +mod p a +mul p 129749 +add p 12345 +mod p a +set b p +mod b 10000 +snd b +add i -1 +jgz i -9 +jgz a 3 +rcv b +jgz b -1 +set f 0 +set i 126 +rcv a +rcv b +set p a +mul p -1 +add p b +jgz p 4 +snd a +set a b +jgz 1 3 +snd b +set f 1 +add i -1 +jgz i -11 +snd a +jgz f -16 +jgz a -19 diff --git a/inputs/input18_test b/inputs/input18_test new file mode 100644 index 0000000..5a093a6 --- /dev/null +++ b/inputs/input18_test @@ -0,0 +1,10 @@ +set a 1 +add a 2 +mul a a +mod a 5 +snd a +set a 0 +rcv a +jgz a -1 +set a 1 +jgz a -2 \ No newline at end of file diff --git a/inputs/input18_test2 b/inputs/input18_test2 new file mode 100644 index 0000000..bf7e168 --- /dev/null +++ b/inputs/input18_test2 @@ -0,0 +1,7 @@ +snd 1 +snd 2 +snd p +rcv a +rcv b +rcv c +rcv d