advent2023/zwanzig.py

72 lines
1.9 KiB
Python
Executable File

#!/usr/bin/env python3
from useful import *
flipflops, conjunctions = {}, {}
broadcaster = []
pulses = defaultdict(lambda: 0)
for line in lines(open(0)):
l, r = line.split(' -> ')
outs = r.split(', ')
if l[0] == '%':
flipflops[l[1:]] = [0, ] + outs
elif l[0] == '&':
conjunctions[l[1:]] = [0, [o for o in outs], {}]
elif l == 'broadcaster':
broadcaster = outs
# may need to set all inputs here
for k, v in flipflops.items():
for o in v[1:]:
if o in conjunctions:
conjunctions[o][2][k] = 0 # phew.
for k, v in conjunctions.items():
for o in v[1]: # 小心
if o in conjunctions:
conjunctions[o][2][k] = 0
def queue_pulse(signal=0, to=broadcaster, fro=None):
global queue
queue += [[signal, to, fro],]
def pulse(signal=0, to=broadcaster, fro=None):
global pulses
pulses[signal] += 1
if to is broadcaster:
for o in to:
pulse(signal, o)
elif to in flipflops:
guy = flipflops[to]
if signal == 0:
guy[0] = 1 - guy[0]
for o in guy[1:]:
queue_pulse(guy[0], o, to)
elif to in conjunctions:
dude, outs, ins = conjunctions[to]
ins[fro] = signal
for o in outs:
if all(ins.values()): # ... are high
queue_pulse(0, o, to)
else:
queue_pulse(1, o, to)
if to == 'rx':
#for node in ('gc sz cm xf zr'.split()):
#if not done[i] and all(conjunctions[node][2].values()):
for node in ('zr',):
if not done[i] and any(conjunctions[node][2].values()):
done[i] = True
print(i)
print(node, conjunctions[node], signal, pulses)
queue = deque()
done = defaultdict(lambda: False)
for i in range(1000000):
pulse()
while queue:
pulse(*queue.popleft())
print(np.prod([n for n in pulses.values()]))