-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.go
181 lines (164 loc) · 11.2 KB
/
main.go
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package main
import (
"fmt"
"sync"
aoc "github.com/tsholmes/aoc-2019"
)
func main() {
part1()
part2()
}
func part1() {
type queue struct {
mu sync.Mutex
vals [][2]int64
curVal [2]int64
curIndex int
}
queues := make([]queue, 50)
in := func(i int) func() int64 {
sentNum := false
return func() int64 {
if !sentNum {
sentNum = true
return int64(i)
}
if queues[i].curIndex == 2 {
queues[i].mu.Lock()
if len(queues[i].vals) > 0 {
queues[i].curVal = queues[i].vals[0]
queues[i].vals = queues[i].vals[1:]
queues[i].curIndex = 0
}
queues[i].mu.Unlock()
}
if queues[i].curIndex == 2 {
return -1
}
v := queues[i].curVal[queues[i].curIndex]
queues[i].curIndex++
return v
}
}
done := make(chan struct{})
out := func(i int) func(int64) {
vs := []int64{}
return func(v int64) {
vs = append(vs, v)
if len(vs) == 3 {
if vs[0] == 255 {
fmt.Println(vs[2])
close(done)
} else {
queues[vs[0]].mu.Lock()
queues[vs[0]].vals = append(queues[vs[0]].vals, [2]int64{vs[1], vs[2]})
queues[vs[0]].mu.Unlock()
}
vs = nil
}
}
}
ics := make([]aoc.IntCode, 50)
for i := range ics {
ics[i] = aoc.LoadIntCode(input, in(i), out(i))
queues[i] = queue{curIndex: 2}
}
for i := range ics {
go ics[i].RunToEnd()
}
<-done
}
func part2() {
type queue struct {
mu sync.Mutex
vals [][2]int64
idle bool
curVal [2]int64
curIndex int
}
var natPack [2]int64
var natLock sync.Mutex
seenY := map[int64]bool{}
done := make(chan struct{})
queues := make([]queue, 50)
in := func(i int) func() int64 {
sentNum := false
return func() int64 {
if !sentNum {
sentNum = true
return int64(i)
}
useNat := false
if queues[i].curIndex == 2 {
queues[i].mu.Lock()
queues[i].idle = false
if len(queues[i].vals) > 0 {
queues[i].curVal = queues[i].vals[0]
queues[i].vals = queues[i].vals[1:]
queues[i].curIndex = 0
} else {
queues[i].idle = true
if i == 0 {
allIdle := true
for j := 1; j < 50; j++ {
queues[j].mu.Lock()
allIdle = allIdle && queues[j].idle && len(queues[j].vals) == 0
queues[j].mu.Unlock()
}
if allIdle {
useNat = true
queues[i].idle = false
}
}
}
queues[i].mu.Unlock()
}
if useNat {
natLock.Lock()
queues[i].curVal = natPack
natLock.Unlock()
if queues[i].curVal[1] != 0 && seenY[queues[i].curVal[1]] {
fmt.Println(queues[i].curVal[1])
close(done)
return -1
}
seenY[queues[i].curVal[1]] = true
queues[i].curIndex = 0
}
if queues[i].curIndex == 2 {
return -1
}
v := queues[i].curVal[queues[i].curIndex]
queues[i].curIndex++
return v
}
}
out := func(i int) func(int64) {
vs := []int64{}
return func(v int64) {
vs = append(vs, v)
if len(vs) == 3 {
if vs[0] == 255 {
natLock.Lock()
natPack = [2]int64{vs[1], vs[2]}
natLock.Unlock()
} else {
queues[vs[0]].mu.Lock()
queues[vs[0]].vals = append(queues[vs[0]].vals, [2]int64{vs[1], vs[2]})
queues[vs[0]].mu.Unlock()
}
vs = nil
}
}
}
ics := make([]aoc.IntCode, 50)
for i := range ics {
ics[i] = aoc.LoadIntCode(input, in(i), out(i))
queues[i] = queue{curIndex: 2}
}
for i := range ics {
go ics[i].RunToEnd()
}
<-done
}
const input = `3,62,1001,62,11,10,109,2255,105,1,0,1396,1583,643,2183,1995,1235,781,977,2026,1037,1791,748,1301,2057,1074,1103,1727,1198,1618,1008,1272,1163,1865,1132,1964,1476,674,1756,1686,1896,810,2088,876,2152,571,1826,1437,1332,845,1649,2214,944,705,1363,610,1552,1507,907,1931,2119,0,0,0,0,0,0,0,0,0,0,0,0,3,64,1008,64,-1,62,1006,62,88,1006,61,170,1106,0,73,3,65,21001,64,0,1,20102,1,66,2,21101,105,0,0,1106,0,436,1201,1,-1,64,1007,64,0,62,1005,62,73,7,64,67,62,1006,62,73,1002,64,2,133,1,133,68,133,101,0,0,62,1001,133,1,140,8,0,65,63,2,63,62,62,1005,62,73,1002,64,2,161,1,161,68,161,1102,1,1,0,1001,161,1,169,102,1,65,0,1102,1,1,61,1101,0,0,63,7,63,67,62,1006,62,203,1002,63,2,194,1,68,194,194,1006,0,73,1001,63,1,63,1106,0,178,21101,210,0,0,105,1,69,2101,0,1,70,1102,0,1,63,7,63,71,62,1006,62,250,1002,63,2,234,1,72,234,234,4,0,101,1,234,240,4,0,4,70,1001,63,1,63,1106,0,218,1106,0,73,109,4,21102,1,0,-3,21101,0,0,-2,20207,-2,67,-1,1206,-1,293,1202,-2,2,283,101,1,283,283,1,68,283,283,22001,0,-3,-3,21201,-2,1,-2,1105,1,263,21202,-3,1,-3,109,-4,2106,0,0,109,4,21101,0,1,-3,21101,0,0,-2,20207,-2,67,-1,1206,-1,342,1202,-2,2,332,101,1,332,332,1,68,332,332,22002,0,-3,-3,21201,-2,1,-2,1106,0,312,22101,0,-3,-3,109,-4,2105,1,0,109,1,101,1,68,359,20101,0,0,1,101,3,68,367,20101,0,0,2,21101,0,376,0,1105,1,436,21201,1,0,0,109,-1,2106,0,0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,109,8,21202,-6,10,-5,22207,-7,-5,-5,1205,-5,521,21102,0,1,-4,21101,0,0,-3,21102,1,51,-2,21201,-2,-1,-2,1201,-2,385,470,21002,0,1,-1,21202,-3,2,-3,22207,-7,-1,-5,1205,-5,496,21201,-3,1,-3,22102,-1,-1,-5,22201,-7,-5,-7,22207,-3,-6,-5,1205,-5,515,22102,-1,-6,-5,22201,-3,-5,-3,22201,-1,-4,-4,1205,-2,461,1106,0,547,21102,-1,1,-4,21202,-6,-1,-6,21207,-7,0,-5,1205,-5,547,22201,-7,-6,-7,21201,-4,1,-4,1106,0,529,21202,-4,1,-7,109,-8,2106,0,0,109,1,101,1,68,563,21001,0,0,0,109,-1,2106,0,0,1102,1,98057,66,1101,5,0,67,1101,598,0,68,1102,1,253,69,1102,1,1,71,1101,0,608,72,1106,0,73,0,0,0,0,0,0,0,0,0,0,43,97379,1101,0,15269,66,1102,1,1,67,1101,0,637,68,1102,1,556,69,1101,0,2,71,1101,639,0,72,1106,0,73,1,13,42,249188,36,290692,1102,1,97169,66,1102,1,1,67,1101,0,670,68,1102,556,1,69,1102,1,1,71,1102,672,1,72,1105,1,73,1,421,30,124934,1101,0,72689,66,1102,1,1,67,1101,701,0,68,1102,1,556,69,1102,1,1,71,1102,703,1,72,1106,0,73,1,23,9,72994,1102,62297,1,66,1101,7,0,67,1101,732,0,68,1102,302,1,69,1102,1,1,71,1101,746,0,72,1106,0,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,37691,1102,1,37783,66,1102,1,1,67,1102,1,775,68,1102,1,556,69,1101,2,0,71,1102,1,777,72,1105,1,73,1,29,42,436079,5,60542,1101,76253,0,66,1101,1,0,67,1102,1,808,68,1101,0,556,69,1102,1,0,71,1101,810,0,72,1106,0,73,1,1567,1101,62467,0,66,1102,3,1,67,1102,837,1,68,1102,1,302,69,1101,1,0,71,1102,843,1,72,1105,1,73,0,0,0,0,0,0,34,392228,1101,0,17891,66,1102,1,1,67,1101,872,0,68,1101,556,0,69,1102,1,1,71,1102,874,1,72,1105,1,73,1,139,39,8324,1102,1,25693,66,1101,1,0,67,1102,903,1,68,1101,556,0,69,1102,1,1,71,1102,905,1,72,1106,0,73,1,16,43,194758,1101,3851,0,66,1102,1,4,67,1102,934,1,68,1101,302,0,69,1101,1,0,71,1101,0,942,72,1106,0,73,0,0,0,0,0,0,0,0,40,18251,1101,9679,0,66,1101,0,1,67,1101,0,971,68,1102,1,556,69,1101,0,2,71,1101,973,0,72,1105,1,73,1,10,47,3851,40,109506,1102,1,50683,66,1102,1,1,67,1101,1004,0,68,1102,556,1,69,1102,1,1,71,1102,1006,1,72,1105,1,73,1,870,9,109491,1102,67853,1,66,1102,1,1,67,1101,0,1035,68,1101,556,0,69,1102,1,0,71,1101,0,1037,72,1105,1,73,1,1392,1101,36497,0,66,1101,0,4,67,1101,0,1064,68,1101,302,0,69,1102,1,1,71,1101,1072,0,72,1106,0,73,0,0,0,0,0,0,0,0,34,294171,1102,1,40499,66,1102,1,1,67,1102,1,1101,68,1102,556,1,69,1101,0,0,71,1101,1103,0,72,1106,0,73,1,1946,1101,40063,0,66,1101,0,1,67,1102,1,1130,68,1101,0,556,69,1101,0,0,71,1101,0,1132,72,1105,1,73,1,1411,1101,0,82781,66,1102,1,1,67,1101,0,1159,68,1102,556,1,69,1101,0,1,71,1102,1,1161,72,1106,0,73,1,-84,30,187401,1101,0,59879,66,1101,3,0,67,1101,1190,0,68,1101,302,0,69,1102,1,1,71,1101,0,1196,72,1105,1,73,0,0,0,0,0,0,48,174962,1102,1,37691,66,1102,4,1,67,1102,1,1225,68,1101,0,253,69,1102,1,1,71,1101,1233,0,72,1106,0,73,0,0,0,0,0,0,0,0,49,83663,1102,30271,1,66,1101,4,0,67,1102,1,1262,68,1101,302,0,69,1101,0,1,71,1102,1270,1,72,1106,0,73,0,0,0,0,0,0,0,0,10,116007,1101,0,24967,66,1101,1,0,67,1102,1299,1,68,1102,556,1,69,1102,1,0,71,1102,1301,1,72,1106,0,73,1,1662,1102,46099,1,66,1101,0,1,67,1101,0,1328,68,1102,1,556,69,1102,1,1,71,1102,1,1330,72,1105,1,73,1,36241,27,20477,1101,19861,0,66,1102,1,1,67,1102,1,1359,68,1101,556,0,69,1102,1,1,71,1102,1,1361,72,1105,1,73,1,3,36,218019,1101,97379,0,66,1101,0,2,67,1102,1390,1,68,1102,302,1,69,1102,1,1,71,1101,1394,0,72,1106,0,73,0,0,0,0,29,86561,1102,5783,1,66,1102,1,1,67,1101,1423,0,68,1102,556,1,69,1102,1,6,71,1101,1425,0,72,1105,1,73,1,22132,48,87481,10,38669,10,77338,1,70999,1,141998,1,212997,1102,1,72673,66,1101,5,0,67,1102,1464,1,68,1101,0,302,69,1101,0,1,71,1101,0,1474,72,1105,1,73,0,0,0,0,0,0,0,0,0,0,34,98057,1101,28697,0,66,1101,0,1,67,1102,1503,1,68,1101,0,556,69,1102,1,1,71,1102,1,1505,72,1105,1,73,1,6400,42,373782,1101,23873,0,66,1102,1,1,67,1101,1534,0,68,1101,556,0,69,1101,8,0,71,1101,1536,0,72,1105,1,73,1,2,42,62297,39,4162,27,40954,29,259683,21,119758,5,30271,40,36502,40,54753,1102,1,36457,66,1101,0,1,67,1102,1,1579,68,1102,1,556,69,1102,1,1,71,1101,1581,0,72,1106,0,73,1,125,47,11553,1101,0,70999,66,1101,0,3,67,1101,0,1610,68,1102,1,302,69,1102,1,1,71,1101,1616,0,72,1105,1,73,0,0,0,0,0,0,17,113073,1102,1,18367,66,1101,1,0,67,1102,1,1645,68,1102,556,1,69,1101,0,1,71,1102,1,1647,72,1106,0,73,1,-195,5,90813,1101,2081,0,66,1101,4,0,67,1102,1,1676,68,1102,302,1,69,1102,1,1,71,1102,1,1684,72,1105,1,73,0,0,0,0,0,0,0,0,34,490285,1102,1,24071,66,1101,0,1,67,1101,1713,0,68,1102,556,1,69,1102,6,1,71,1101,1715,0,72,1105,1,73,1,5,42,186891,29,173122,21,59879,47,7702,47,15404,40,91255,1102,2593,1,66,1102,1,1,67,1101,0,1754,68,1102,556,1,69,1102,0,1,71,1102,1756,1,72,1105,1,73,1,1553,1101,20477,0,66,1101,0,3,67,1101,1783,0,68,1102,1,302,69,1102,1,1,71,1101,0,1789,72,1105,1,73,0,0,0,0,0,0,34,196114,1102,38669,1,66,1101,3,0,67,1101,0,1818,68,1101,0,302,69,1101,1,0,71,1102,1824,1,72,1106,0,73,0,0,0,0,0,0,17,150764,1102,37199,1,66,1101,1,0,67,1101,1853,0,68,1102,1,556,69,1101,5,0,71,1101,1855,0,72,1106,0,73,1,1,30,62467,36,363365,39,6243,27,61431,9,145988,1102,1,99689,66,1101,0,1,67,1102,1,1892,68,1102,1,556,69,1102,1,1,71,1102,1894,1,72,1105,1,73,1,4,5,121084,1101,0,86561,66,1101,0,3,67,1101,1923,0,68,1102,1,302,69,1101,0,1,71,1102,1929,1,72,1106,0,73,0,0,0,0,0,0,21,179637,1101,87481,0,66,1101,0,2,67,1101,0,1958,68,1102,302,1,69,1102,1,1,71,1102,1,1962,72,1106,0,73,0,0,0,0,17,75382,1101,0,6473,66,1102,1,1,67,1101,1991,0,68,1102,1,556,69,1101,0,1,71,1102,1993,1,72,1105,1,73,1,47,9,36497,1102,32563,1,66,1101,0,1,67,1101,0,2022,68,1102,1,556,69,1102,1,1,71,1101,0,2024,72,1105,1,73,1,-167,36,72673,1101,61151,0,66,1102,1,1,67,1101,2053,0,68,1101,556,0,69,1101,0,1,71,1102,1,2055,72,1106,0,73,1,7,36,145346,1102,1,27791,66,1101,1,0,67,1102,2084,1,68,1102,556,1,69,1102,1,1,71,1101,2086,0,72,1106,0,73,1,769,42,124594,1101,4871,0,66,1102,1,1,67,1102,2115,1,68,1102,556,1,69,1101,1,0,71,1101,0,2117,72,1106,0,73,1,-245,39,2081,1102,1,83663,66,1102,1,2,67,1101,2146,0,68,1101,351,0,69,1101,1,0,71,1102,2150,1,72,1106,0,73,0,0,0,0,255,5783,1101,0,997,66,1102,1,1,67,1102,2179,1,68,1101,0,556,69,1102,1,1,71,1102,2181,1,72,1106,0,73,1,59,42,311485,1102,48397,1,66,1101,1,0,67,1102,2210,1,68,1101,0,556,69,1101,0,1,71,1101,2212,0,72,1105,1,73,1,160,40,73004,1101,0,18251,66,1102,1,6,67,1101,2241,0,68,1102,1,302,69,1101,1,0,71,1102,2253,1,72,1105,1,73,0,0,0,0,0,0,0,0,0,0,0,0,49,167326`