-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
124 lines (105 loc) · 2.14 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
package main
import (
"fmt"
"io"
"os"
"github.com/devries/advent_of_code_2021/utils"
)
func main() {
f, err := os.Open("../inputs/day11.txt")
utils.Check(err, "error opening input.txt")
defer f.Close()
r := solve(f)
fmt.Println(r)
}
func solve(r io.Reader) int {
lines := utils.ReadLines(r)
grid, xlen, ylen := parseGrid(lines)
gen := 0
for {
gen++
flashcount := step(grid)
if flashcount == xlen*ylen {
break
}
}
return gen
}
func parseGrid(lines []string) (map[utils.Point]int, int, int) {
r := make(map[utils.Point]int)
xlen := 0
ylen := 0
for j, ln := range lines {
for i, c := range ln {
r[utils.Point{X: i, Y: j}] = int(c - '0')
if xlen < i {
xlen = i
}
}
if ylen < j {
ylen = j
}
}
return r, xlen + 1, ylen + 1
}
var neighbors = []utils.Point{{X: -1, Y: -1}, {X: -1, Y: 0}, {X: -1, Y: 1}, {X: 0, Y: -1}, {X: 0, Y: 1}, {X: 1, Y: -1}, {X: 1, Y: 0}, {X: 1, Y: 1}}
// Step by one and return number of flashes
func step(grid map[utils.Point]int) int {
// Increment each by one, saving those that are flashing
flashers := make([]utils.Point, 0)
for k, v := range grid {
grid[k] = v + 1
if v >= 9 {
flashers = append(flashers, k)
}
}
// Flash the flashers and and increment neighbors, if there are new flashers then append them
flashcount := 0
flashedPoints := make(map[utils.Point]bool) // Track which points have flashed already
for len(flashers) > 0 {
p := flashers[0]
flashers = flashers[1:]
if flashedPoints[p] {
continue // We already did this one
}
for _, n := range neighbors {
pn := p.Add(n)
if flashedPoints[pn] {
// Already flashed, skip it
continue
}
v, ok := grid[pn]
if !ok {
continue // outside grid
}
grid[pn] = v + 1
if v >= 9 {
flashers = append(flashers, pn)
}
}
grid[p] = 0
flashedPoints[p] = true
flashcount++
}
// displayGrid(grid)
return flashcount
}
func displayGrid(grid map[utils.Point]int) {
i := 0
j := 0
for {
v, ok := grid[utils.Point{X: i, Y: j}]
if !ok {
if i == 0 {
fmt.Printf("\n")
break
}
j++
i = 0
fmt.Printf("\n")
continue
}
fmt.Printf("%d", v)
i++
}
}