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

Commit 3f1efe3

Browse files
committed
Update day 20 part 1 to support custom number of cheat seconds
1 parent 49e4f16 commit 3f1efe3

File tree

1 file changed

+49
-17
lines changed

1 file changed

+49
-17
lines changed

solutions/day20/main.go

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,8 @@ func part1(
2626

2727
cheatCounts := make(map[int]int)
2828
for _, pos := range path {
29-
distance := dm[pos.Y][pos.X]
30-
next := []util.Coordinate{
31-
pos.North().North(),
32-
pos.South().South(),
33-
pos.East().East(),
34-
pos.West().West(),
35-
}
36-
37-
for _, nPos := range next {
38-
// Normally moving two steps should give us two less distance,
39-
// so these 2 are subtracted from the saved amount.
40-
nDistance := dm[nPos.Y][nPos.X]
41-
saved := nDistance - distance - 2
42-
if saved > 0 {
43-
cheatCounts[saved] += 1
44-
}
29+
for k, v := range findAllCheats(dm, pos, 2) {
30+
cheatCounts[k] += v
4531
}
4632
}
4733

@@ -50,12 +36,58 @@ func part1(
5036
if k >= 100 {
5137
count += v
5238
}
53-
fmt.Printf("There are %d cheats that save %d picoseconds.\n", v, k)
5439
}
5540

5641
return fmt.Sprintf("Number of cheats saving at least 100ps: %d", count)
5742
}
5843

44+
func findAllCheats(
45+
dm distanceMap,
46+
pos util.Coordinate,
47+
steps int,
48+
) map[int]int {
49+
// Initialize visited set
50+
visited := make(map[intY]map[intX]bool)
51+
for y := range dm {
52+
visited[y] = make(map[intX]bool)
53+
}
54+
55+
cheats := make(map[int]int)
56+
positions := pos.Adjacent4()
57+
distance := dm[pos.Y][pos.X]
58+
for step := 1; step <= steps; step++ {
59+
newPositions := make([]util.Coordinate, 0, 4*len(positions))
60+
for _, p := range positions {
61+
// 1. Check if in visited set, if it is then skip.
62+
if visited[p.Y][p.X] || visited[p.Y] == nil {
63+
continue
64+
}
65+
visited[p.Y][p.X] = true
66+
67+
// 2. Calculate time saved
68+
// Moving here normally will take $step number of steps, so savings
69+
// are calculated by subtracting step from the distance map.
70+
nDistance := dm[p.Y][p.X]
71+
saved := nDistance - distance - step
72+
73+
if nDistance != 0 && saved <= 0 {
74+
// 3. If we didn't save time by going this way, continue.
75+
continue
76+
} else if nDistance != 0 {
77+
// 4. We didn't save time by going here, but we're still in the wilderness
78+
cheats[saved] += 1
79+
}
80+
81+
// 5. This position is not trash, lets add all it's neighbors to the new positions set
82+
newPositions = append(newPositions, p.Adjacent4()...)
83+
}
84+
85+
positions = newPositions
86+
}
87+
88+
return cheats
89+
}
90+
5991
func (p parsedInput) createDistanceMap() (distanceMap, []util.Coordinate, error) {
6092
newM := make(distanceMap)
6193
path := make([]util.Coordinate, 0, p.length)

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