aoc2024/day-18/internal/one/solve.go

77 lines
1.4 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/queue"
log "github.com/sirupsen/logrus"
)
var ShortestPath []Point
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]()
queue.Enqueue(graph.start)
visited := make(map[Point]struct{})
costs := make(map[Point]int)
prev := make(map[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 = []Point{graph.end}
node := prev[graph.end]
for node != graph.start {
ShortestPath = append(ShortestPath, prev[node])
node = prev[node]
}
log.Debugf("\n%s\n", graph.debug(ShortestPath))
return len(ShortestPath), nil
}