@@ -6,11 +6,13 @@ import (
6
6
"fmt"
7
7
"github.com/lizthegrey/adventofcode/2019/intcode"
8
8
"os"
9
+ "sort"
9
10
"strings"
10
11
"sync"
11
12
)
12
13
13
14
var inputFile = flag .String ("inputFile" , "inputs/day25.input" , "Relative file path to use as input." )
15
+ var debug = flag .Bool ("debug" , true , "Whether to print debug output." )
14
16
15
17
var disallow = []string {
16
18
"giant electromagnet" ,
@@ -60,46 +62,61 @@ func main() {
60
62
return
61
63
}
62
64
65
+ inputs := 0
66
+
63
67
input := make (chan int , 1 )
64
68
output , done := tape .Process (input )
65
69
lines := make (chan string , 50 )
66
70
driver := make (chan string )
71
+ reallyFinished := make (chan bool )
67
72
68
73
go func () {
69
74
line := make ([]byte , 0 )
70
75
for c := range output {
71
- if c > 255 {
72
- fmt .Println (c )
73
- return
76
+ if * debug {
77
+ fmt .Printf ("%c" , c )
74
78
}
75
- fmt .Printf ("%c" , c )
76
79
77
80
if c == '\n' {
81
+ if len (line ) > 0 && line [0 ] == '"' {
82
+ fmt .Println (string (line ))
83
+ fmt .Printf ("Completed with %d inputs.\n " , inputs )
84
+ break
85
+ }
78
86
lines <- string (line )
79
87
line = make ([]byte , 0 )
80
88
} else {
81
89
line = append (line , byte (c ))
82
90
}
83
91
}
84
- fmt .Println ()
92
+ if * debug {
93
+ fmt .Println ()
94
+ }
95
+ <- done
96
+ reallyFinished <- true
85
97
}()
86
98
87
- go func () {
88
- reader := bufio .NewReader (os .Stdin )
89
- for {
90
- line , err := reader .ReadString ('\n' )
91
- if line == "\n " || err != nil {
92
- return
93
- }
94
- for _ , r := range line {
95
- input <- int (r )
99
+ if * debug {
100
+ go func () {
101
+ reader := bufio .NewReader (os .Stdin )
102
+ for {
103
+ line , err := reader .ReadString ('\n' )
104
+ if line == "\n " || err != nil {
105
+ return
106
+ }
107
+ for _ , r := range line {
108
+ input <- int (r )
109
+ }
96
110
}
97
- }
98
- }()
111
+ }()
112
+ }
99
113
100
114
go func () {
101
115
for l := range driver {
102
- fmt .Printf ("[Automated]: %s\n " , l )
116
+ inputs ++
117
+ if * debug {
118
+ fmt .Printf ("[Automated]: %s\n " , l )
119
+ }
103
120
for _ , r := range l {
104
121
input <- int (r )
105
122
}
@@ -112,10 +129,13 @@ func main() {
112
129
go func () {
113
130
var loc Loc
114
131
rooms := make (Maze )
115
- var items []string
132
+ seenItems := make (map [string ]bool )
133
+ var allItems , items []string
116
134
var outbound []Direction
117
135
var q Queue
118
136
var arrived * Exit
137
+ checkpointTry := 0
138
+
119
139
parseMode := 0
120
140
parse:
121
141
for l := range lines {
@@ -142,27 +162,28 @@ func main() {
142
162
}
143
163
parseMode = 0
144
164
} else if l [0 ] == '-' {
145
- // This is a list.
146
- // Doors here lead:
147
- // - north
148
- //
149
- // Items here:
150
- // - cake
151
165
if parseMode == 1 {
152
166
outbound = append (outbound , Direction (l [2 :]))
153
167
} else if parseMode == 2 {
154
168
items = append (items , l [2 :])
169
+ } else if parseMode == 3 {
170
+ // Do nothing.
155
171
} else {
156
172
fmt .Println ("Didn't know what to do with a list outside parse mode." )
157
173
}
158
174
} else if l [len (l )- 1 ] == ':' {
159
175
// This is a menu ("Doors here lead:" or "Items here:").
160
- keyword := strings .Split (l , " " )[0 ]
176
+ keywords := strings .Split (l [:len (l )- 1 ], " " )
177
+ keyword := keywords [0 ]
161
178
switch keyword {
162
179
case "Doors" :
163
180
parseMode = 1
164
181
case "Items" :
165
- parseMode = 2
182
+ if keywords [1 ] == "here" {
183
+ parseMode = 2
184
+ } else {
185
+ parseMode = 3
186
+ }
166
187
default :
167
188
fmt .Println ("Unknown menu type." )
168
189
}
@@ -184,6 +205,10 @@ func main() {
184
205
}
185
206
if ! skip {
186
207
driver <- fmt .Sprintf ("take %s" , item )
208
+ if ! seenItems [item ] {
209
+ allItems = append (allItems , item )
210
+ seenItems [item ] = true
211
+ }
187
212
continue parse
188
213
}
189
214
}
@@ -197,37 +222,54 @@ func main() {
197
222
}
198
223
// Pick a direction to move.
199
224
next := nextDirection (& q , loc , rooms )
200
- if next == q .target .dir && loc == q .target .src {
225
+ if q . target != nil && next == q .target .dir && loc == q .target .src {
201
226
arrived = q .target
202
227
q .target = nil
203
228
}
204
229
if next == "dance" {
205
- done <- true
230
+ // Now we can move onto phase 2 and access the security checkpoint.
231
+ next = "west"
232
+ sort .Strings (allItems )
233
+ for _ , v := range itemsToDrop (allItems , checkpointTry ) {
234
+ driver <- fmt .Sprintf ("drop %s" , v )
235
+ <- lines
236
+ <- lines
237
+ <- lines
238
+ <- lines
239
+ }
240
+ checkpointTry ++
206
241
}
207
242
driver <- string (next )
208
243
} else {
209
- fmt .Println ("Got into somewhere we can't leave" )
244
+ if * debug {
245
+ fmt .Println ("Got into somewhere we can't leave" )
246
+ }
210
247
}
211
248
} else {
212
249
// This is presumed to be flavor text or a response to command.
213
250
// Just let the program print.
214
251
}
215
252
}
216
253
}()
217
- <- done
254
+ <- reallyFinished
218
255
}
219
256
220
257
type Queue struct {
221
258
mtx sync.Mutex
222
259
list []Exit
223
260
target * Exit
261
+ sensor * Exit
224
262
}
225
263
226
264
func notifyRoom (q * Queue , ex Exit , rooms Maze ) {
227
265
q .mtx .Lock ()
266
+ defer q .mtx .Unlock ()
228
267
q .list = append (q .list , ex )
268
+ if ex .src == "Security Checkpoint" {
269
+ q .sensor = & ex
270
+ return
271
+ }
229
272
rooms [ex.src ][ex.dir ] = ex
230
- q .mtx .Unlock ()
231
273
}
232
274
233
275
func nextDirection (q * Queue , loc Loc , rooms Maze ) Direction {
@@ -243,7 +285,6 @@ func nextDirection(q *Queue, loc Loc, rooms Maze) Direction {
243
285
}
244
286
// We've reached our destination and need a new destination.
245
287
if len (q .list ) == 0 {
246
- fmt .Println ("Nothing left to explore. Result:" )
247
288
return "dance"
248
289
}
249
290
@@ -269,7 +310,6 @@ func nextDirection(q *Queue, loc Loc, rooms Maze) Direction {
269
310
270
311
func bfs (src Loc , dst Exit , rooms Maze ) []Direction {
271
312
// Perform a breadth-first search.
272
-
273
313
shortest := map [Loc ][]Direction {
274
314
src : []Direction {},
275
315
}
@@ -299,3 +339,14 @@ func bfs(src Loc, dst Exit, rooms Maze) []Direction {
299
339
worklist = worklist [1 :]
300
340
}
301
341
}
342
+
343
+ func itemsToDrop (all []string , try int ) []string {
344
+ var ret []string
345
+ for k := range all {
346
+ if try % 2 == 1 {
347
+ ret = append (ret , all [k ])
348
+ }
349
+ try >>= 1
350
+ }
351
+ return ret
352
+ }
0 commit comments