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

+49-17
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)