Skip to content
This repository was archived by the owner on Dec 28, 2024. It is now read-only.

Commit 5817dbe

Browse files
committed
Add solution day 18 part 2
1 parent ca5d2a8 commit 5817dbe

File tree

2 files changed

+77
-40
lines changed

2 files changed

+77
-40
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ automatically rebuilt and redeployed every time the `common` module or their own
5050
| 02 | ⭐ ⭐ | 15 | ⭐ ⭐ |
5151
| 03 | ⭐ ⭐ | 16 | ⭐ 🥸 |
5252
| 04 | ⭐ ⭐ | 17 ||
53-
| 05 | ⭐ ⭐ | 18 | |
53+
| 05 | ⭐ ⭐ | 18 | |
5454
| 06 | ⭐ ⭐ | 19 | |
5555
| 07 | ⭐ ⭐ | 20 | |
5656
| 08 | ⭐ ⭐ | 21 | |

solutions/day18/main.go

Lines changed: 76 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,68 +7,77 @@ import (
77
)
88

99
func main() {
10-
common.Setup(18, part1, nil)
10+
common.Setup(18, part1, part2)
1111
}
1212

1313
func part1(
1414
input string,
1515
) string {
16-
out, err := run(input, 70, 70, 1024)
16+
m := buildMatrix()
17+
cs, err := parse(input)
1718
if err != nil {
18-
return err.Error()
19+
return fmt.Sprintf("Failed to parse input: %v", err)
1920
}
20-
return fmt.Sprintf("Shortest path is %d steps", out)
21+
22+
for _, c := range cs[:1024] {
23+
m[c.Y][c.X] = true
24+
}
25+
26+
start := util.Coordinate{X: 0, Y: 0}
27+
end := util.Coordinate{X: 70, Y: 70}
28+
visitedSet := buildVisitedSet[int]()
29+
shortestPath(m, start, end, 0, visitedSet)
30+
31+
shortest := visitedSet[70][70]
32+
return fmt.Sprintf("Shortest path is %d steps", shortest)
2133
}
2234

23-
func run(
35+
func part2(
2436
input string,
25-
maxX int,
26-
maxY int,
27-
fallenBytes int,
28-
) (int, error) {
29-
m := buildMatrix(maxX, maxY)
37+
) string {
38+
m := buildMatrix()
3039
cs, err := parse(input)
3140
if err != nil {
32-
return -1, err
41+
return fmt.Sprintf("Failed to parse input: %v", err)
3342
}
3443

35-
if len(cs) > fallenBytes {
36-
cs = cs[:fallenBytes]
37-
}
44+
// Initialize everything
45+
latest := cs[0]
46+
cs = cs[1:]
47+
winningSet := buildVisitedSet[bool]()
48+
m[latest.Y][latest.X] = true
49+
count := 1
50+
start := util.Coordinate{X: 0, Y: 0}
51+
end := util.Coordinate{X: 70, Y: 70}
52+
success := anyPath(m, start, end, buildVisitedSet[bool](), winningSet)
3853

39-
for _, c := range cs {
40-
m[c.Y][c.X] = true
41-
}
54+
for success && len(cs) > 0 {
55+
for !winningSet[latest.Y][latest.X] && len(cs) > 0 {
56+
count++
57+
latest = cs[0]
58+
cs = cs[1:]
59+
m[latest.Y][latest.X] = true
60+
}
4261

43-
visitedSet := buildVisitedSet(maxY)
44-
shortestPath(
45-
m,
46-
util.Coordinate{X: 0, Y: 0},
47-
util.Coordinate{X: maxX, Y: maxY},
48-
0,
49-
visitedSet,
50-
)
62+
winningSet = buildVisitedSet[bool]()
63+
success = anyPath(m, start, end, buildVisitedSet[bool](), winningSet)
64+
}
5165

52-
return visitedSet[maxY][maxX], nil
66+
return fmt.Sprintf("The byte that broke the camel's back was %s", latest)
5367
}
5468

55-
func buildMatrix(
56-
maxX int,
57-
maxY int,
58-
) [][]bool {
59-
out := make([][]bool, maxY+1)
60-
for y := 0; y <= maxY; y++ {
61-
out[y] = make([]bool, maxX+1)
69+
func buildMatrix() [][]bool {
70+
out := make([][]bool, 71)
71+
for y := 0; y <= 70; y++ {
72+
out[y] = make([]bool, 71)
6273
}
6374
return out
6475
}
6576

66-
func buildVisitedSet(
67-
maxY int,
68-
) map[int]map[int]int {
69-
visitedSet := make(map[int]map[int]int)
70-
for y := 0; y <= maxY; y++ {
71-
visitedSet[y] = make(map[int]int)
77+
func buildVisitedSet[T any]() map[int]map[int]T {
78+
visitedSet := make(map[int]map[int]T)
79+
for y := 0; y <= 70; y++ {
80+
visitedSet[y] = make(map[int]T)
7281
}
7382
return visitedSet
7483
}
@@ -106,3 +115,31 @@ func shortestPath(
106115
shortestPath(m, c.South(), goal, steps+1, visitedSet)
107116
shortestPath(m, c.West(), goal, steps+1, visitedSet)
108117
}
118+
119+
func anyPath(
120+
m [][]bool,
121+
c util.Coordinate,
122+
goal util.Coordinate,
123+
visitedSet map[int]map[int]bool,
124+
winningSet map[int]map[int]bool,
125+
) bool {
126+
if visitedSet[c.Y][c.X] || !util.In2DArray(c, m) || m[c.Y][c.X] {
127+
// Been here, outside matrix or position is impassable
128+
return false
129+
} else if c.Equals(goal) {
130+
// We did it!
131+
winningSet[c.Y][c.X] = true
132+
return true
133+
}
134+
135+
visitedSet[c.Y][c.X] = true
136+
winner := anyPath(m, c.South(), goal, visitedSet, winningSet) ||
137+
anyPath(m, c.East(), goal, visitedSet, winningSet) ||
138+
anyPath(m, c.West(), goal, visitedSet, winningSet) ||
139+
anyPath(m, c.North(), goal, visitedSet, winningSet)
140+
if winner {
141+
winningSet[c.Y][c.X] = true
142+
}
143+
144+
return winner
145+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy