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

Commit 4797aa0

Browse files
committed
Add solution day 21 part 2 - AoC 2024 is DONE!
1 parent e100721 commit 4797aa0

File tree

3 files changed

+61
-35
lines changed

3 files changed

+61
-35
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ automatically rebuilt and redeployed every time the `common` module or their own
5353
| 05 | ⭐ ⭐ | 18 | ⭐ ⭐ |
5454
| 06 | ⭐ ⭐ | 19 | ⭐ ⭐ |
5555
| 07 | ⭐ ⭐ | 20 | ⭐ ⭐ |
56-
| 08 | ⭐ ⭐ | 21 | |
56+
| 08 | ⭐ ⭐ | 21 | |
5757
| 09 | ⭐ ⭐ | 22 | ⭐ ⭐ |
5858
| 10 | ⭐ ⭐ | 23 | ⭐ ⭐ |
5959
| 11 | ⭐ ⭐ | 24 | ⭐ ⭐ |
60-
| 12 | ⭐ ⭐ | 25 | |
60+
| 12 | ⭐ ⭐ | 25 | |
6161
| 13 | ⭐ ⭐ | | |

solutions/day21/keypad.go

+39-7
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@ import (
77
var numStart = util.Coordinate{X: 2, Y: 3}
88
var dirStart = util.Coordinate{X: 2, Y: 0}
99

10+
type cacheMap = map[cacheKey]int
11+
type cacheKey struct {
12+
path string
13+
depth int
14+
}
15+
1016
// Char to Pos on numeric keypad
1117
func charToPosNum(
12-
c int,
18+
c byte,
1319
) util.Coordinate {
1420
switch c {
1521
case '0':
@@ -25,7 +31,7 @@ func charToPosNum(
2531

2632
// Char to Pos on directional keypad
2733
func charToPosDir(
28-
c int,
34+
c byte,
2935
) util.Coordinate {
3036
switch c {
3137
case '^':
@@ -44,8 +50,8 @@ func charToPosDir(
4450
func shortestPath(
4551
start, end util.Coordinate,
4652
useNumPad bool,
47-
) []int {
48-
var path []int
53+
) []byte {
54+
var path []byte
4955
dx := end.X - start.X
5056
dy := end.Y - start.Y
5157
pVert, pHor := buildPath(dx, dy)
@@ -71,14 +77,40 @@ func shortestPath(
7177
return path
7278
}
7379

80+
func dfs(
81+
cache cacheMap,
82+
key cacheKey,
83+
) int {
84+
out := 0
85+
if v, ok := cache[key]; ok {
86+
return v
87+
} else if key.depth == 0 {
88+
return len(key.path)
89+
}
90+
91+
subPaths := make([][]byte, len(key.path))
92+
prev := dirStart
93+
for i, c := range key.path {
94+
curr := charToPosDir(byte(c))
95+
subPaths[i] = shortestPath(prev, curr, false)
96+
prev = curr
97+
}
98+
99+
for _, subPath := range subPaths {
100+
out += dfs(cache, cacheKey{path: string(subPath), depth: key.depth - 1})
101+
}
102+
cache[key] = out
103+
return out
104+
}
105+
74106
func buildPath(
75107
dx int,
76108
dy int,
77-
) ([]int, []int) {
109+
) ([]byte, []byte) {
78110
adx := util.AbsInt(dx)
79111
ady := util.AbsInt(dy)
80-
pVert := make([]int, ady)
81-
pHor := make([]int, adx)
112+
pVert := make([]byte, ady)
113+
pHor := make([]byte, adx)
82114

83115
for i := range adx {
84116
if dx < 0 {

solutions/day21/main.go

+20-26
Original file line numberDiff line numberDiff line change
@@ -7,47 +7,41 @@ import (
77
"strings"
88
)
99

10-
func main() {
11-
common.Setup(21, part1, nil)
12-
}
10+
func main() { common.Setup(21, part1, part2) }
11+
12+
func part1(input string) string { return solve(input, 2) }
13+
func part2(input string) string { return solve(input, 25) }
1314

14-
func part1(
15+
func solve(
1516
input string,
17+
robots int,
1618
) string {
17-
var out string
19+
cache := make(cacheMap)
1820

1921
sequences := strings.Split(input, "\n")
2022
sum := 0
2123
for _, code := range sequences {
24+
codeNumeric, err := strconv.Atoi(code[:len(code)-1])
25+
if err != nil {
26+
return fmt.Sprintf("Failed to parse code %s as int: %v", code, err)
27+
}
28+
2229
// Five is the longest path between two keys on numeric pad
23-
path := make([]int, 0, 5*len(code))
30+
path := make([][]byte, 0, 5*len(code))
2431
prev := numStart
2532
for _, c := range code {
26-
curr := charToPosNum(int(c))
27-
path = append(path, shortestPath(prev, curr, true)...)
33+
curr := charToPosNum(byte(c))
34+
path = append(path, shortestPath(prev, curr, true))
2835
prev = curr
2936
}
3037

31-
for range 2 {
32-
// Three is the longest path between two keys on directional pad
33-
newPath := make([]int, 0, 3*len(path))
34-
prev = dirStart
35-
for _, c := range path {
36-
curr := charToPosDir(c)
37-
newPath = append(newPath, shortestPath(prev, curr, false)...)
38-
prev = curr
39-
}
40-
path = newPath
41-
}
42-
43-
codeNumeric, err := strconv.Atoi(code[:len(code)-1])
44-
if err != nil {
45-
return fmt.Sprintf("Failed to parse code %s as int: %v", code, err)
38+
pathLen := 0
39+
for _, c := range path {
40+
pathLen += dfs(cache, cacheKey{path: string(c), depth: robots})
4641
}
4742

48-
sum += len(path) * codeNumeric
43+
sum += pathLen * codeNumeric
4944
}
5045

51-
out += fmt.Sprintf("Sum: %d", sum)
52-
return out
46+
return fmt.Sprintf("Sum: %d", sum)
5347
}

0 commit comments

Comments
 (0)