package day12 import ( "fmt" "strings" "adventofcode2022/utils" "adventofcode2022/utils/grid2d" ) type cell struct { height int distance int } type coord struct { x int y int } func Part1(input string) int { startCoord, grid := parseInput(input) fillGrid(grid) printGrid(grid) c := grid.Get(startCoord.x, startCoord.y) return c.distance } func Part2(input string) int { _, grid := parseInput(input) fillGrid(grid) min := utils.MaxInt for j := 0; j < grid.SizeY(); j++ { for i := 0; i < grid.SizeX(); i++ { c1 := grid.Get(i, j) if c1.height == 0 { min = utils.Min(min, c1.distance) } } } return min } func parseInput(input string) (coord, *grid2d.Grid[*cell]) { lines := strings.Split(input, "\n") grid := grid2d.NewGrid[*cell](len(lines[0]), len(lines), nil) startCoord := coord{-1, -1} for j, line := range lines { for i, c := range line { newCell := &cell{height: int(c - 'a'), distance: utils.MaxInt} if c == 'S' { newCell.height = 0 startCoord.x = i startCoord.y = j } else if c == 'E' { newCell.height = 25 newCell.distance = 0 } grid.Set(i, j, newCell) } } return startCoord, grid } func fillGrid(grid *grid2d.Grid[*cell]) { done := false for !done { done = true for j := 0; j < grid.SizeY(); j++ { for i := 0; i < grid.SizeX(); i++ { c1 := grid.Get(i, j) if c1.distance == utils.MaxInt { continue } moves := [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}} for _, move := range moves { x2 := i + move[0] y2 := j + move[1] c2 := grid.Get(x2, y2) if c2 == nil { continue } if c2.height < c1.height-1 { continue } if c2.distance > c1.distance+1 { c2.distance = c1.distance + 1 done = false } } } } } } func printGrid(grid *grid2d.Grid[*cell]) { r := grid.StringWithFormatter(func(c *cell, i, j int) string { if c.distance == utils.MaxInt { return "?? " } return fmt.Sprintf("%02d ", c.distance) }) fmt.Println(r) }