package main import ( "os" "fmt" "strconv" "strings" ) // data types type Path struct { start_x int start_y int end_x int end_y int } // general util func check(e error) { if e != nil { panic(e) } } func get_next_steps(field [][]byte, path *Path) []Path { paths := make([]Path, 0, 4) x := path.end_x y := path.end_y val := field[y][x] if y < len(field) - 1 { down := field[y + 1][x] if down == val + 1 { paths = append(paths, Path{ start_x: path.start_x, start_y: path.start_y, end_x: x, end_y: y + 1 }) } } if y > 0 { up := field[y - 1][x] if up == val + 1 { paths = append(paths, Path{ start_x: path.start_x, start_y: path.start_y, end_x: x, end_y: y - 1 }) } } if x < len(field[0]) - 1 { right := field[y][x + 1] if right == val + 1 { paths = append(paths, Path{ start_x: path.start_x, start_y: path.start_y, end_x: x + 1, end_y: y }) } } if x > 0 { left := field[y][x - 1] if left == val + 1 { paths = append(paths, Path{ start_x: path.start_x, start_y: path.start_y, end_x: x - 1, end_y: y }) } } return paths } func get_all_paths(field [][]byte) []Path { paths := make([]Path, 0) // init for _y, line := range field { for _x, val := range line { if val == 0 { paths = append(paths, Path{start_x: _x, end_x: _x, start_y: _y, end_y: _y}) } } } // step by step for i := 0; i < 9; i++ { new_paths := make([]Path, 0, len(paths)) for _, path := range paths { new_paths = append(new_paths, get_next_steps(field, &path)...) } paths = new_paths } return paths } // main loop func main() { // read in file dat, err := os.ReadFile("data.txt") check(err) dat_str := strings.TrimSpace(string(dat)) // contruct input as byte matrix lines := strings.Split(dat_str, "\n") input := make([][]byte, 0, len(lines)) for _, line := range lines { matrix_line := make([]byte, 0, len(line)) for _, char := range []rune(line) { num, err := strconv.Atoi(string(char)) check(err) matrix_line = append(matrix_line, byte(num)) } input = append(input, matrix_line) } // calc rating fmt.Println(len(get_all_paths(input))) }