mirror of
https://github.com/onyx-and-iris/aoc2024.git
synced 2025-01-09 22:30:47 +00:00
73 lines
1.3 KiB
Go
73 lines
1.3 KiB
Go
package one
|
|
|
|
import (
|
|
"bytes"
|
|
"math"
|
|
|
|
"github.com/onyx-and-iris/aoc2024/day-20/internal/point"
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"github.com/elliotchance/orderedmap/v3"
|
|
)
|
|
|
|
const cheatChar = 'X'
|
|
|
|
var Path *orderedmap.OrderedMap[point.Point, int]
|
|
|
|
func Solve(buf []byte) (int, error) {
|
|
r := bytes.NewReader(buf)
|
|
graph, err := parseLines(r)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
Path = orderedmap.NewOrderedMap[point.Point, int]()
|
|
Path.Set(graph.start, 0)
|
|
Path = graph.path(graph.start, Path, 1)
|
|
log.Debugf("initial path: %d\n", Path.Len()-1)
|
|
log.Debugf("Unique path:\n%s\n", graph.debug(Path))
|
|
|
|
visited := make(map[point.Point]struct{})
|
|
|
|
var sum int
|
|
for point := range Path.Keys() {
|
|
for dir, n := range neighbours(point) {
|
|
if graph.isOutOfBounds(n) {
|
|
continue
|
|
}
|
|
|
|
if graph.valueAt(n) != '#' {
|
|
continue
|
|
}
|
|
|
|
if _, ok := visited[n]; ok {
|
|
continue
|
|
}
|
|
|
|
if graph.isValidCheatPosition(n) {
|
|
b := graph.getConnectingPoint(direction(dir), n)
|
|
graph.set(n, 'X')
|
|
|
|
v1, ok := Path.Get(point)
|
|
if !ok {
|
|
log.Fatalf("%v not in path", point)
|
|
}
|
|
v2, ok := Path.Get(b)
|
|
if !ok {
|
|
log.Fatalf("%v not in path", b)
|
|
}
|
|
diff := int(math.Abs(float64(v1-v2))) - 1
|
|
|
|
log.Debugf("diff: %d\n", diff)
|
|
if diff >= 100 {
|
|
sum++
|
|
}
|
|
|
|
visited[n] = struct{}{}
|
|
}
|
|
}
|
|
}
|
|
|
|
return sum, nil
|
|
}
|