package main import ( "AOC2022/helper" "fmt" ) type ActivePath struct { activePosition [2]int visitedPositions [][2]int steps int } type FieldPoint struct { cost int height int } func main() { //args := os.Args[1:] lines := helper.ReadTextFile("day12/input") start, end := getStartingPointAndEndpoint(lines) fmt.Println(start) fmt.Println(end) field := getField(lines) activePaths := []ActivePath{{start, [][2]int{}, 0}} fastestRoute := 999999999 for len(activePaths) > 0 { newPaths := []ActivePath{} for _, path := range activePaths { if path.activePosition == [2]int{2, 6} { //fmt.Println("here") } newPathStep := path.step(field) if path.activePosition == end && fastestRoute > path.steps { fastestRoute = path.steps path.print(field) } else if path.steps < fastestRoute { newPaths = append(newPaths, newPathStep...) } } activePaths = newPaths } fmt.Println(fastestRoute) } func getField(lines []string) [][]FieldPoint { field := make([][]FieldPoint, len(lines)) for i := 0; i < len(lines); i++ { line := lines[i] fieldLine := make([]FieldPoint, len(line)) for j := 0; j < len(line); j++ { height := int(line[j]) if line[j] == 'S' { height = int('a') } if line[j] == 'E' { height = int('z') } fieldLine[j] = FieldPoint{0, height} } } return field } func (path *ActivePath) step(field []string) (newPaths []ActivePath) { if getHeight(path.activePosition, field) == 'E' { return } nextSteps := path.getNextStep(field) for _, step := range nextSteps { newPath := ActivePath{step, append(path.visitedPositions, path.activePosition), path.steps + 1} newPaths = append(newPaths, newPath) } return } func (path *ActivePath) checkVisitable(direction [2]int, field []string) (visitable bool) { toVisit := path.activePosition toVisit[0] += direction[0] toVisit[1] += direction[1] if toVisit[0] > -1 && toVisit[1] > -1 && toVisit[0] < len(field) && toVisit[1] < len((field)[0]) { if helper.Contains2Int(path.visitedPositions, toVisit) { return false } heightToVisit := getHeight(toVisit, field) heightCurrentPos := getHeight(path.activePosition, field) + 1 if heightToVisit > heightCurrentPos { return false } return true } return false } func (path ActivePath) getNextStep(field []string) (nextSteps [][2]int) { directions := [][2]int{{0, -1}, {0, +1}, {-1, 0}, {+1, 0}} for _, direction := range directions { if path.checkVisitable(direction, field) { newStep := [2]int{path.activePosition[0] + direction[0], path.activePosition[1] + direction[1]} nextSteps = append(nextSteps, newStep) } } return } func getHeight(location [2]int, field []string) int { if field[location[0]][location[1]] == 'S' { return 'a' } if field[location[0]][location[1]] == 'E' { return 'z' } return int(field[location[0]][location[1]]) } func getStartingPointAndEndpoint(field []string) (start, end [2]int) { for i := 0; i < len(field); i++ { for j := 0; j < len(field[i]); j++ { if field[i][j] == 'S' { start = [2]int{i, j} } if field[i][j] == 'E' { end = [2]int{i, j} } } } return } func (path ActivePath) print(field []string) { for i := 0; i < len(field); i++ { tempArr := "" for j := 0; j < len(field[i]); j++ { if helper.Contains2Int(path.visitedPositions, [2]int{i, j}) { tempArr += "#" } else { tempArr += "." } } fmt.Println(tempArr) } }