-
Notifications
You must be signed in to change notification settings - Fork 0
/
day23.py
63 lines (47 loc) · 1.72 KB
/
day23.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
62
63
"""
--- Day 23: Category Six ---
https://adventofcode.com/2019/day/23
"""
import aocd
from .intcode import IntComputer
PROGRAM = [int(n) for n in aocd.data.split(",")]
def part_a():
comps = [IntComputer(PROGRAM, (index,)) for index in range(50)]
while True:
for comp in comps:
try:
comp.run(IntComputer.op_output)
except IndexError:
comp.input.append(-1) # no packet in the queue
if len(comp.output) >= 3:
dest, *pkt = (comp.output.popleft() for _ in range(3))
if dest == 255:
return pkt[1]
else:
comps[dest].input.extend(pkt)
print("Part One:", part_a())
def empty(queue):
return not queue or queue[0] == -1
def part_b():
nat, last_nat = None, None
comps = [IntComputer(PROGRAM, (index,)) for index in range(50)]
while True:
for index, comp in enumerate(comps):
try:
comp.run(IntComputer.op_output)
except IndexError:
# if the network is idle use the NAT
if nat and index == 0 and all(empty(c.input) and not c.output for c in comps):
comp.input.extend(nat)
if last_nat and last_nat[1] == nat[1]:
return nat[1]
last_nat = nat
else:
comp.input.append(-1) # no packet in the queue
if len(comp.output) >= 3:
dest, *pkt = (comp.output.popleft() for _ in range(3))
if dest == 255:
nat = pkt
else:
comps[dest].input.extend(pkt)
print("Part Two:", part_b())