Skip to content

Commit a4a39d4

Browse files
committed
day20: probably solved part two, but too slow
1 parent 56ebc0b commit a4a39d4

File tree

1 file changed

+44
-32
lines changed

1 file changed

+44
-32
lines changed

day20/main.go

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -91,60 +91,72 @@ type cheat struct {
9191
end util.Point
9292
}
9393

94-
func findCheats(course [][]byte, moves []util.Point, startIdx int, minSaving int, cheatedWalls map[util.Point]util.Void) []cheat {
94+
func findCheats(course [][]byte, moves []util.Point, startIdx int, minSaving int, debug bool) []cheat {
9595
var s = moves[startIdx]
9696
var cheats []cheat
97-
for _, d := range directions {
98-
var w = s.Add(d)
99-
if !w.IsInBounds(len(course), len(course[w.Y])) {
100-
continue
101-
}
102-
if course[w.Y][w.X] != WALL {
103-
continue
104-
}
105-
var e = w.Add(d)
106-
var ei = findMoveIdx(moves, e)
107-
// HINT: save 100 picoseconds, but this includes two additional steps
108-
if ei-startIdx < minSaving+2 {
109-
// TODO: might there be multiple cheats forward?
110-
continue
97+
var visited = make(map[util.Point]int)
98+
var recents = make(map[util.Point]int)
99+
recents[s] = 0
100+
for len(recents) > 0 {
101+
var found = make(map[util.Point]int)
102+
for p1, cost := range recents {
103+
for _, d := range directions {
104+
var p2 = p1.Add(d)
105+
if !p2.IsInBounds(len(course), len(course[p1.Y])) {
106+
continue
107+
}
108+
if _, ok := visited[p2]; ok {
109+
continue
110+
}
111+
if course[p2.Y][p2.X] == WALL {
112+
visited[p2] = cost + 1
113+
found[p2] = cost + 1
114+
continue
115+
}
116+
var endIdx = findMoveIdx(moves, p2)
117+
var saving = endIdx - startIdx - cost - 1
118+
if saving < minSaving {
119+
continue
120+
}
121+
if debug {
122+
fmt.Printf("%d picoseconds saved by cheat: %d,%d -> %d,%d\n", saving, s.Y, s.X, p2.Y, p2.X)
123+
}
124+
cheats = append(cheats, cheat{start: s, end: p2})
125+
}
111126
}
112-
cheatedWalls[w] = util.Void{}
113-
fmt.Printf("%d picoseconds saved by cheat: %d,%d -> %d,%d\n", ei-startIdx-2, s.Y, s.X, e.Y, e.X)
114-
cheats = append(cheats, cheat{start: s, end: e})
127+
recents = found
115128
}
116-
return cheats
117-
}
118-
119-
func printCourseWithCheats(course [][]byte, cheats map[util.Point]util.Void) {
120-
for y := range course {
121-
for x := range course[y] {
122-
if _, ok := cheats[util.Point{Y: y, X: x}]; ok {
123-
fmt.Print("C")
124-
} else {
125-
fmt.Print(string(course[y][x]))
129+
if debug {
130+
for y := range course {
131+
for x := range course[y] {
132+
if cost, ok := visited[util.Point{Y: y, X: x}]; ok {
133+
fmt.Print(cost % 10)
134+
} else {
135+
fmt.Print(string(course[y][x]))
136+
}
126137
}
138+
fmt.Println()
127139
}
128140
fmt.Println()
129141
}
130-
fmt.Println()
142+
return cheats
131143
}
132144

133145
func main() {
134146
var minSaving = flag.Int("minSaving", 100, "consider cheats that save at least minSaving picoseconds")
147+
var debug = flag.Bool("debug", false, "verbose output")
135148
flag.Parse()
136149

137150
var course = readCourse()
138151
var moves = findMoves(course)
139152
var time = len(moves) - 1
140153
fmt.Printf("course takes %d picoseconds\n", time)
141154
var cheats = make(map[cheat]util.Void)
142-
var cheatedWalls = make(map[util.Point]util.Void)
143155
for i := range moves {
144-
for _, c := range findCheats(course, moves, i, *minSaving, cheatedWalls) {
156+
for _, c := range findCheats(course, moves, i, *minSaving, *debug) {
145157
cheats[c] = util.Void{}
146158
}
159+
fmt.Printf("searched cheats for %d/%d moves\n", i+1, len(moves))
147160
}
148-
printCourseWithCheats(course, cheatedWalls)
149161
fmt.Printf("found %d unique cheats saving >= %d picoseconds", len(cheats), *minSaving)
150162
}

0 commit comments

Comments
 (0)