-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday20.py
61 lines (48 loc) · 1.61 KB
/
day20.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import re
from math import lcm
destinations, types, state, conjunctions = {}, {}, {}, {}
for s in open('input20.txt', 'r').readlines():
key = re.findall(r'(&?%?\w+)\s*->', s)[0]
values = [c.strip() for c in re.findall(r'->\s*(.*)', s)[0].split(',')]
if key != 'broadcaster':
types[key[1:]] = key[0]
key = key[1:]
else:
types[key] = key
state[key] = -1
destinations[key] = values
for k, t in types.items():
conjunctions[k] = {i:-1 for i, ds in destinations.items() if t == '&' and k in ds}
def run(todo, i):
hi, lo = 0, 0
while todo:
key, last_key, pulse = todo.pop(0)
if pulse == 1: hi += 1
else: lo += 1
if key not in types.keys(): continue
type = types[key]
if type == '%':
if pulse == 1: continue
pulse *= state[key]
state[key] = pulse
elif type == '&':
conjunctions[key][last_key] = pulse
pulse = -1 if all(map(lambda p: p == 1, conjunctions[key].values())) else 1
if pulse == 1 and key in conjunctions[rx_parent].keys():
cycles[key].append(i)
for d in destinations[key]:
todo.append((d, key, pulse))
return hi, lo
hi, lo = 0, 0
i = 0
rx_parent = [p for p, ds in destinations.items() if 'rx' in ds][0]
cycles = {p:[] for p in conjunctions[rx_parent]}
while not all(map(lambda l: len(l) >= 2, cycles.values())):
i += 1
h, l = run([('broadcaster', 'button', -1)], i)
if i <= 1000:
hi, lo = hi+h, lo+l
# part 1
print(hi*lo)
# part 2
print(lcm(*(l[1]-l[0] for l in cycles.values())))