1
1
package main
2
2
3
3
import (
4
- "bufio"
5
4
"io"
6
5
"math"
7
6
@@ -24,6 +23,8 @@ func fs1(input io.Reader) int {
24
23
25
24
type Grid struct {
26
25
board [][]bool
26
+
27
+ rec * Rec
27
28
}
28
29
29
30
func (g * Grid ) String () string {
@@ -120,12 +121,239 @@ func toGrid(lines []string) *Grid {
120
121
}
121
122
}
122
123
123
- func fs2 (input io.Reader ) int {
124
- scanner := bufio .NewScanner (input )
125
- for scanner .Scan () {
126
- line := scanner .Text ()
127
- _ = line
124
+ func fs2 (input io.Reader , minutes int ) int {
125
+ grid := toGridRec (lib .ReaderToStrings (input ))
126
+
127
+ rec := grid .rec
128
+ for i := 0 ; i < minutes ; i ++ {
129
+ rec = rec .round ()
130
+ }
131
+
132
+ return rec .countBugs ()
133
+ }
134
+
135
+ func toGridRec (lines []string ) * Grid {
136
+ var board [][]bool
137
+ for _ , line := range lines {
138
+ var row []bool
139
+ for i := 0 ; i < len (line ); i ++ {
140
+ if line [i ] == '#' {
141
+ row = append (row , true )
142
+ } else {
143
+ row = append (row , false )
144
+ }
145
+ }
146
+ board = append (board , row )
147
+ }
148
+ return & Grid {
149
+ rec : & Rec {board : board },
150
+ }
151
+ }
152
+
153
+ type Rec struct {
154
+ inside * Rec
155
+ outside * Rec
156
+ board [][]bool
157
+ }
158
+
159
+ func newBoard () [][]bool {
160
+ res := make ([][]bool , 5 )
161
+ for i := 0 ; i < 5 ; i ++ {
162
+ res [i ] = make ([]bool , 5 )
163
+ }
164
+ return res
165
+ }
166
+
167
+ func containsBug (board [][]bool ) bool {
168
+ for row := 0 ; row < 5 ; row ++ {
169
+ for col := 0 ; col < 5 ; col ++ {
170
+ if board [row ][col ] {
171
+ return true
172
+ }
173
+ }
174
+ }
175
+ return false
176
+ }
177
+
178
+ func (r * Rec ) round () * Rec {
179
+ res := make ([][]bool , 5 )
180
+ for i := 0 ; i < 5 ; i ++ {
181
+ res [i ] = make ([]bool , 5 )
182
+ }
183
+
184
+ if containsBug (r .board ) {
185
+ if r .outside == nil {
186
+ r .outside = & Rec {
187
+ inside : r ,
188
+ board : newBoard (),
189
+ }
190
+ r .outside .round ()
191
+ return r .outside
192
+ }
193
+ if r .inside == nil {
194
+ r .inside = & Rec {
195
+ outside : r ,
196
+ board : newBoard (),
197
+ }
198
+ }
199
+ }
200
+
201
+ for row := 0 ; row < 5 ; row ++ {
202
+ for col := 0 ; col < 5 ; col ++ {
203
+ if row == 2 && col == 2 {
204
+ continue
205
+ }
206
+ res [row ][col ] = r .isBugRec (lib.Position {row , col })
207
+ }
128
208
}
129
209
130
- return 42
210
+ if r .inside != nil {
211
+ _ = r .inside .round ()
212
+ }
213
+ r .board = res
214
+
215
+ return r
216
+ }
217
+
218
+ func (r * Rec ) get (pos lib.Position ) int {
219
+ if pos .Row < 0 || pos .Col < 0 || pos .Row >= 5 || pos .Col >= 5 {
220
+ return 0
221
+ }
222
+
223
+ if r.board [pos.Row ][pos.Col ] {
224
+ return 1
225
+ }
226
+ return 0
227
+ }
228
+
229
+ func (r * Rec ) countBugs () int {
230
+ sum := 0
231
+ for row := 0 ; row < 5 ; row ++ {
232
+ for col := 0 ; col < 5 ; col ++ {
233
+ if row == 2 && col == 2 {
234
+ continue
235
+ }
236
+ if r.board [row ][col ] {
237
+ sum ++
238
+ }
239
+ }
240
+ }
241
+
242
+ if r .inside != nil {
243
+ sum += r .inside .countBugs ()
244
+ }
245
+ return sum
246
+ }
247
+
248
+ func (r * Rec ) getOutside (pos lib.Position ) int {
249
+ if r .outside == nil {
250
+ return 0
251
+ }
252
+ return r .outside .get (pos )
253
+ }
254
+
255
+ func (r * Rec ) getInside (pos lib.Position ) int {
256
+ if r .inside == nil {
257
+ return 0
258
+ }
259
+ return r .inside .get (pos )
260
+ }
261
+
262
+ /*
263
+ A B C D E
264
+ F G H I J
265
+ K L x N O
266
+ P Q R S T
267
+ U V W X Y
268
+ */
269
+ func (r * Rec ) sumAdjacent (pos lib.Position ) int {
270
+ sum := 0
271
+
272
+ // 4 "normal"
273
+ sum += r .get (pos .Delta (- 1 , 0 ))
274
+ sum += r .get (pos .Delta (1 , 0 ))
275
+ sum += r .get (pos .Delta (0 , - 1 ))
276
+ sum += r .get (pos .Delta (0 , 1 ))
277
+
278
+ if pos .Row == 0 {
279
+ sum += r .getOutside (H )
280
+ }
281
+ if pos .Row == 4 {
282
+ sum += r .getOutside (R )
283
+ }
284
+ if pos .Col == 0 {
285
+ sum += r .getOutside (L )
286
+ }
287
+ if pos .Col == 4 {
288
+ sum += r .getOutside (N )
289
+ }
290
+
291
+ if pos == H {
292
+ sum += r .getInside (A ) +
293
+ r .getInside (B ) +
294
+ r .getInside (C ) +
295
+ r .getInside (D ) +
296
+ r .getInside (E )
297
+ }
298
+
299
+ if pos == R {
300
+ sum += r .getInside (U ) +
301
+ r .getInside (V ) +
302
+ r .getInside (W ) +
303
+ r .getInside (X ) +
304
+ r .getInside (Y )
305
+ }
306
+
307
+ if pos == L {
308
+ sum += r .getInside (A ) +
309
+ r .getInside (F ) +
310
+ r .getInside (K ) +
311
+ r .getInside (P ) +
312
+ r .getInside (U )
313
+ }
314
+
315
+ if pos == N {
316
+ sum += r .getInside (E ) +
317
+ r .getInside (J ) +
318
+ r .getInside (O ) +
319
+ r .getInside (T ) +
320
+ r .getInside (Y )
321
+ }
322
+
323
+ return sum
324
+ }
325
+
326
+ var (
327
+ A = lib.Position {0 , 0 }
328
+ B = lib.Position {0 , 1 }
329
+ C = lib.Position {0 , 2 }
330
+ D = lib.Position {0 , 3 }
331
+ E = lib.Position {0 , 4 }
332
+ F = lib.Position {1 , 0 }
333
+ G = lib.Position {1 , 1 }
334
+ H = lib.Position {1 , 2 }
335
+ I = lib.Position {1 , 3 }
336
+ J = lib.Position {1 , 4 }
337
+ K = lib.Position {2 , 0 }
338
+ L = lib.Position {2 , 1 }
339
+ N = lib.Position {2 , 3 }
340
+ O = lib.Position {2 , 4 }
341
+ P = lib.Position {3 , 0 }
342
+ Q = lib.Position {3 , 1 }
343
+ R = lib.Position {3 , 2 }
344
+ S = lib.Position {3 , 3 }
345
+ T = lib.Position {3 , 4 }
346
+ U = lib.Position {4 , 0 }
347
+ V = lib.Position {4 , 1 }
348
+ W = lib.Position {4 , 2 }
349
+ X = lib.Position {4 , 3 }
350
+ Y = lib.Position {4 , 4 }
351
+ )
352
+
353
+ func (r * Rec ) isBugRec (pos lib.Position ) bool {
354
+ sum := r .sumAdjacent (pos )
355
+ if r.board [pos.Row ][pos.Col ] {
356
+ return sum == 1
357
+ }
358
+ return sum == 1 || sum == 2
131
359
}
0 commit comments