-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathday23.py
executable file
·83 lines (60 loc) · 1.66 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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env python3
import sys
from lib.intcode import IntcodeVM
from collections import deque
def vm_read_for(self):
def vm_read():
if self.packet_queue:
self.idle = False
self.unserviced_reads = 0
return self.packet_queue.popleft()
self.unserviced_reads += 1
if self.unserviced_reads > 1:
self.idle = True
return -1
return vm_read
def vm_write_for(self):
def vm_write(v):
global nat_packet
self.idle = False
self.unserviced_reads = 0
self.out_packet.append(v)
if len(self.out_packet) == 3:
destination, *packet = self.out_packet
self.out_packet = []
if destination == 255:
nat_packet = packet
else:
network[destination].packet_queue.extend(packet)
return vm_write
# Open the first argument as input or use stdin if no arguments were given
fin = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin
program = list(map(int, fin.read().split(',')))
network = [IntcodeVM(program) for _ in range(50)]
nat_packet = None
for i, vm in enumerate(network):
vm.read = vm_read_for(vm)
vm.write = vm_write_for(vm)
vm.idle = False
vm.unserviced_reads = 0
vm.packet_queue = deque([i])
vm.out_packet = []
while nat_packet is None:
for vm in network:
vm.run(n_in=1, resume=True)
last_nat_y = nat_packet[1]
print('Part 1:', last_nat_y)
last_nat_y = None
done = False
while not done:
for vm in network:
vm.run(n_in=1, resume=True)
if all(vm.idle for vm in network):
if nat_packet[1] == last_nat_y:
done = True
break
network[0].idle = False
network[0].packet_queue.extend(nat_packet)
last_nat_y = nat_packet[1]
nat_packet = []
print('Part 2:', last_nat_y)