with open('input.text', 'r') as file: data: list[str] = file.readlines() topo_map = [[int(c) if c != '.' else -1 for c in line.strip()] for line in data] x_bound: int = len(topo_map[0]) - 1 y_bound: int = len(topo_map) - 1 class Coord: x: int y: int def __init__(self, x: int, y: int): self.x = x self.y = y def __str__(self) -> str: return f'({self.x}, {self.y})' def __eq__(self, o) -> bool: return o.x == self.x and o.y == self.y def in_bounds(c: Coord) -> bool: if c.y > y_bound or c.y < 0: return False if c.x > x_bound or c.x < 0: return False return True def score_trail(c: Coord, last: int | None = 0) -> list[Coord]: if not in_bounds(c): return None v: int = topo_map[c.y][c.x] if v == 9: return [c] if v - last != 1 and last != 0: return None up, down, left, right = Coord(c.x, c.y - 1), Coord(c.x, c.y + 1), Coord(c.x - 1, c.y), Coord(c.x + 1, c.y) nines = [] for dir in [up, down, left, right]: if in_bounds(dir): if topo_map[dir.y][dir.x] - v == 1: for nine in score_trail(dir, v): if nine not in nines: nines.append(nine) return nines total = 0 for y, line in enumerate(topo_map): for x, n in enumerate(line): if n == 0: total += len(score_trail(Coord(x, y))) print(total)