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 }