mirror of
https://github.com/onyx-and-iris/aoc2024.git
synced 2025-01-09 14:20:48 +00:00
81 lines
1.6 KiB
Go
81 lines
1.6 KiB
Go
package one
|
|
|
|
import (
|
|
"bytes"
|
|
"math"
|
|
|
|
"github.com/onyx-and-iris/aoc2024/day-18/internal/config"
|
|
"github.com/onyx-and-iris/aoc2024/day-18/internal/point"
|
|
"github.com/onyx-and-iris/aoc2024/day-18/internal/queue"
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
orderedmap "github.com/wk8/go-ordered-map/v2"
|
|
)
|
|
|
|
var ShortestPath *orderedmap.OrderedMap[point.Point, struct{}]
|
|
|
|
func Solve(buf []byte, config config.Config) (int, error) {
|
|
r := bytes.NewReader(buf)
|
|
graph, err := parseLines(r, config)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
log.Debugf("start: %v end: %v", graph.start, graph.end)
|
|
|
|
log.Debugf("\n%s\n", graph.String())
|
|
queue := queue.New[point.Point]()
|
|
queue.Enqueue(graph.start)
|
|
visited := make(map[point.Point]struct{})
|
|
costs := make(map[point.Point]int)
|
|
prev := make(map[point.Point]point.Point)
|
|
|
|
for !queue.IsEmpty() {
|
|
current := queue.Dequeue()
|
|
|
|
if current == graph.end {
|
|
break
|
|
}
|
|
|
|
_, ok := visited[current]
|
|
if ok {
|
|
continue
|
|
}
|
|
visited[current] = struct{}{}
|
|
|
|
for _, n := range neighbours(current) {
|
|
if graph.isOutOfBounds(n) {
|
|
continue
|
|
}
|
|
|
|
if graph.valueAt(n) == '#' {
|
|
continue
|
|
}
|
|
|
|
_, ok := costs[n]
|
|
if !ok {
|
|
costs[n] = math.MaxInt
|
|
}
|
|
|
|
new_cost := costs[current] + 1
|
|
if new_cost < costs[n] {
|
|
costs[n] = new_cost
|
|
prev[n] = current
|
|
queue.Enqueue(n)
|
|
}
|
|
}
|
|
}
|
|
|
|
ShortestPath = orderedmap.New[point.Point, struct{}]()
|
|
ShortestPath.Set(graph.end, struct{}{})
|
|
node := prev[graph.end]
|
|
for node != graph.start {
|
|
ShortestPath.Set(node, struct{}{})
|
|
node = prev[node]
|
|
}
|
|
|
|
log.Debugf("\n%s\n", graph.debug(ShortestPath))
|
|
|
|
return ShortestPath.Len(), nil
|
|
}
|