Skip to content

Instantly share code, notes, and snippets.

@vjeranc
Created December 20, 2023 07:36
Show Gist options
  • Save vjeranc/1e63789057e49c4f23092b963034fbd3 to your computer and use it in GitHub Desktop.
Save vjeranc/1e63789057e49c4f23092b963034fbd3 to your computer and use it in GitHub Desktop.
from collections import *
from math import *
O, I = defaultdict(list), defaultdict(list)
FLIP, CONJ = set(), set()
for l in open(0):
a, bs = l.strip().split(' -> ')
a = a.strip()
if a[0]=='%':
a = a[1:]
FLIP.add(a)
if a[0]=='&':
a = a[1:]
CONJ.add(a)
for b in bs.split(', '):
b = b.strip()
O[a].append(b)
I[b].append(a)
O['button'] = ['broadcaster']
print(O, I)
P2 = True
if P2:
assert 'rx' not in FLIP and 'rx' not in CONJ
assert len(I['rx'])==1
assert I['rx'][0] in CONJ
L, H = 0, 0
S = defaultdict(lambda: 'low')
cycles = {i: 0 for i in I[I['rx'][0]]} # input specific lcm luck
for i in range(10**9 if P2 else 1000):
if P2 and all(cycles.values()): break
PS = [('button', 'low')] # pulses
while PS:
if P2 and all(cycles.values()): break
NPS = []
for c, p in PS:
if c not in O: continue
if c in FLIP and p=='high': continue
s, outs = S[c], O[c]
if c in FLIP and p=='low':
S[c] = s = 'low' if s=='high' else 'high'
elif c in CONJ:
S[c] = s = 'low' if all(S[b]=='high' for b in I[c]) else 'high'
if s=='low': L += len(outs)
if s=='high': H += len(outs)
if P2 and c in cycles and s=='high' and cycles[c]==0:
cycles[c] = i+1 # cannot be 0
if all(cycles.values()): break
# for ch in chs:
# print(c, f'-{s}->', ch)
for p in outs:
NPS += [(p, s)]
else:
PS = NPS
if not P2: print(L, H, L*H)
if P2: print(lcm(*cycles.values()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment