88 lines
1.6 KiB
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
|
|
}
|