adventofcode/2022/day12/main.go

88 lines
1.6 KiB
Go

package main
import (
"fmt"
"math"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
inp := h.StdinToStringSlice()
part1(inp)
fmt.Println()
part2(inp)
}
func part1(inp []string) {
m := h.StringSliceToCoordByteMap(inp)
start, _ := m.FindFirst('S')
m.Put(start, 'a')
end, _ := m.FindFirst('E')
m.Put(end, 'z')
fmt.Println("# Part 1")
fmt.Println("Steps:", bfs(m, start, end))
}
func part2(inp []string) {
m := h.StringSliceToCoordByteMap(inp)
starts := m.FindAll('a')
if s, err := m.FindFirst('S'); err == nil {
m.Put(s, 'a')
starts = append(starts, s)
}
end, _ := m.FindFirst('E')
m.Put(end, 'z')
minSteps := math.MaxInt
for _, start := range starts {
curSteps := bfs(m, start, end)
if minSteps > curSteps {
minSteps = curSteps
}
}
fmt.Println("# Part 2")
fmt.Println("Steps:", minSteps)
}
func bfs(m h.CoordByteMap, start, end h.Coordinate) int {
seen := make(map[h.Coordinate]bool)
seen[start] = true
queue := []h.Coordinate{start}
steps := 0
found := false
// BFS Search
SEARCH:
for len(queue) > 0 {
k := len(queue)
for i := 0; i < k; i++ {
curr := queue[0]
currVal := m.Get(curr)
queue = queue[1:]
if end.Equals(curr) {
found = true
break SEARCH
}
for _, dir := range curr.GetOrthNeighbors() {
if !m.ContainsCoord(dir) || seen[dir] {
continue
}
newVal := m.Get(dir)
greater := m.Get(dir) > currVal
if greater && newVal-currVal > 1 {
continue
}
seen[dir] = true
queue = append(queue, dir)
}
}
steps++
}
if !found {
//fmt.Println("Path from", start, "to", end, "not found!")
return math.MaxInt
}
return steps
}