7
7
)
8
8
9
9
func main () {
10
- common .Setup (16 , part1 , nil )
10
+ common .Setup (16 , part1 , part2 )
11
11
}
12
12
13
13
func part1 (
@@ -20,50 +20,84 @@ func part1(
20
20
21
21
// Initialize visited set with end point
22
22
set := initializeVisitedSet (i )
23
- loop (initialReindeer (i .s ), i , set )
23
+ loop (initialReindeer (i .s ), i , set , initializeWinningSet ( i ), - 1 )
24
24
25
25
return fmt .Sprintf ("Cheapest path: %v" , lowestSoFar (i , set ))
26
26
}
27
27
28
+ func part2 (
29
+ input string ,
30
+ ) string {
31
+ i , err := parse (input )
32
+ if err != nil {
33
+ return fmt .Sprintf ("Failed to parse input: %v" , err )
34
+ }
35
+
36
+ // Initialize visited set with end point
37
+ visited := initializeVisitedSet (i )
38
+ loop (initialReindeer (i .s ), i , visited , initializeWinningSet (i ), - 1 )
39
+
40
+ // Run again with the correct answer, which should weed out
41
+ // all paths that were the best before better paths were found.
42
+ winners := initializeWinningSet (i )
43
+ answer := lowestSoFar (i , visited )
44
+ loop (initialReindeer (i .s ), i , initializeVisitedSet (i ), winners , answer )
45
+ winners [i .e .Y ][i .e .X ] = true
46
+
47
+ count := 0
48
+ for _ , ys := range winners {
49
+ count += len (ys )
50
+ }
51
+
52
+ return fmt .Sprintf ("Best seats: %d" , count )
53
+ }
54
+
28
55
func loop (
29
56
r reindeer ,
30
57
i parsedInput ,
31
58
set visitedSet ,
32
- ) {
33
- if r .visitAndCheckIfDead (set ) {
34
- return
59
+ winners winningSet ,
60
+ answer int ,
61
+ ) bool {
62
+ isWinner := false
63
+ if r .visitAndCheckIfDead (set , answer != - 1 ) {
64
+ return false
35
65
}
36
66
37
67
lowest := lowestSoFar (i , set )
38
- if lowest != 0 && r .score > lowest {
39
- return
68
+ if answer == - 1 && lowest != 0 && r .score > lowest {
69
+ winners [r .p .Y ][r .p .X ] = true
70
+ return false
40
71
}
41
72
42
73
if r .p .Equals (i .e ) {
43
- return
74
+ if answer == - 1 {
75
+ return true
76
+ } else {
77
+ return r .score == answer
78
+ }
44
79
}
45
80
46
81
newR , err := r .forward (i .m )
47
- if err == nil {
48
- loop ( newR , i , set )
82
+ if err == nil && loop ( newR , i , set , winners , answer ) {
83
+ isWinner = true
49
84
}
50
85
51
86
newR , err = r .turnClockwise ().forward (i .m )
52
- if err == nil {
53
- loop ( newR , i , set )
87
+ if err == nil && loop ( newR , i , set , winners , answer ) {
88
+ isWinner = true
54
89
}
55
90
56
- newR , err = r .turnClockwise (). turnClockwise ().forward (i .m )
57
- if err == nil {
58
- loop ( newR , i , set )
91
+ newR , err = r .turnCounterClockwise ().forward (i .m )
92
+ if err == nil && loop ( newR , i , set , winners , answer ) {
93
+ isWinner = true
59
94
}
60
95
61
- newR , err = r .turnCounterClockwise ().forward (i .m )
62
- if err == nil {
63
- loop (newR , i , set )
96
+ if isWinner {
97
+ winners [r .p .Y ][r .p .X ] = true
64
98
}
65
99
66
- return
100
+ return isWinner
67
101
}
68
102
69
103
func lowestSoFar (
@@ -85,3 +119,13 @@ func initializeVisitedSet(
85
119
}
86
120
return set
87
121
}
122
+
123
+ func initializeWinningSet (
124
+ i parsedInput ,
125
+ ) winningSet {
126
+ set := make (winningSet )
127
+ for y , _ := range i .m {
128
+ set [y ] = make (map [intX ]bool )
129
+ }
130
+ return set
131
+ }
0 commit comments