-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday16-2.go
69 lines (65 loc) · 1.26 KB
/
day16-2.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
package main
import (
"fmt"
"log"
)
func day16part2(filename string) (string, error) {
f, err := day16ReadMap(filename)
if err != nil {
return "", err
}
var e int
starts := f.startPositions()
for i, v := range starts {
log.Printf("Run %d of %d...", i+1, len(starts))
e = max(e, f.runFrom(v))
}
return fmt.Sprint(e), nil
}
func (f day16Field) startPositions() []day16Step {
var starts []day16Step
// Horizontal beams, inward from both sides.
for y := 0; y < len(f); y++ {
starts = append(starts, day16Step{
day16Pos{y, 0},
day16East,
})
starts = append(starts, day16Step{
day16Pos{y, len(f[y]) - 1},
day16West,
})
}
// Vertical beams, inward from both sides.
for x := 0; x < len(f[0]); x++ {
starts = append(starts, day16Step{
day16Pos{0, x},
day16South,
})
starts = append(starts, day16Step{
day16Pos{len(f) - 1, x},
day16North,
})
}
return starts
}
func (f day16Field) runFrom(start day16Step) int {
e := make(day16Ener)
eLen := len(e)
eSame := 0
q := day16Queue{start}
for len(q) > 0 && eSame < 10000000 {
next := q[0]
q = q[1:]
for _, s := range f.step(next) {
q = append(q, s)
}
e[next.pos] = true
if eLen == len(e) {
eSame += 1
} else {
eLen = len(e)
eSame = 0
}
}
return len(e)
}