package main import ( "fmt" h "git.bullercodeworks.com/brian/adventofcode/helpers" ) func main() { inp := h.StdinToStringSlice() // size, bytes := 6, 12 // Test Input size, bytes := 70, 1024 // Actual Input part1(inp, size, bytes) fmt.Println() part2(inp, size, bytes) } func part1(inp []string, size, bytes int) { // bytes:= 12 // Test Input m := h.NewCoordByteMap() m.BRX, m.BRY = size, size drops := parseInput(inp) for i := 0; i < bytes; i++ { m.Put(drops[i], '#') } fmt.Println("# Part 1") fmt.Println(FindShortestPath(m, func(a, b State) bool { return a.cnt+a.dist < b.cnt+b.dist })) } func part2(inp []string, size, bytes int) { m := h.NewCoordByteMap() m.BRX, m.BRY = size, size drops := parseInput(inp) // We can skip up to 'bytes', part1 showed that that many work for i := 0; i < bytes; i++ { m.Put(drops[i], '#') } fmt.Println("# Part 2") for tm, b := range drops[bytes+1:] { m.Put(b, '#') if FindShortestPath(m, func(a, b State) bool { return a.dist < b.dist }) == -1 { fmt.Printf("Blocked at %d: %s\n", bytes+tm, b.String()) return } } } func parseInput(inp []string) []h.Coordinate { var ret []h.Coordinate for i := range inp { c := h.Coordinate{} fmt.Sscanf(inp[i], "%d,%d", &c.X, &c.Y) ret = append(ret, c) } return ret } type State struct { c h.Coordinate cnt int dist int } func FindShortestPath(inp h.CoordByteMap, less func(a, b State) bool) int { visited := make(map[h.Coordinate]State) end := h.Coordinate{X: inp.BRX, Y: inp.BRY} start := h.Coordinate{X: 0, Y: 0} startState := State{ c: start, cnt: 0, dist: start.Distance(end), } queue := h.NewHeap[State](less) queue.Push(startState) for queue.Len() > 0 { step := queue.Pop() if step.c.Equals(end) { visited[end] = step break } if _, ok := visited[step.c]; ok { continue } visited[step.c] = step // Find next steps for _, n := range step.c.GetOrthNeighbors() { if !inp.ContainsCoord(n) || inp.Get(n) == '#' { continue } if _, ok := visited[n]; ok { continue } nState := State{ c: n, cnt: step.cnt + 1, dist: n.Distance(end), } queue.Push(nState) } } if v, ok := visited[end]; ok { return v.cnt } return -1 }