import fileinput from collections import deque map = [] start_pos = None end_pos = None for y, row in enumerate(fileinput.input(mode="rb")): row = row.strip() if not row: continue r = [] for x, col in enumerate(row): match col: case 83: start_pos = (x, y) r.append(0) case 69: end_pos = (x, y) r.append(25) case _: r.append(col - 97) map.append(r) assert start_pos is not None assert end_pos is not None part1, part2 = None, None trace: tuple[tuple[int, int], ...] = () stack = deque([(0, end_pos, trace)]) visited = set() while stack: h_, (x, y), trace = stack.popleft() if x < 0 or x >= len(map[0]) or y < 0 or y >= len(map) or (x, y) in visited: continue h = map[y][x] if h - h_ < -1: continue if part1 is None and (x, y) == start_pos: part1 = len(trace) if part2 is None and h == 0: part2 = len(trace) if part1 is not None and part2 is not None: break visited.add((x, y)) trace = trace + ((x, y, h),) stack.append((h, (x - 1, y + 0), trace)) stack.append((h, (x + 1, y + 0), trace)) stack.append((h, (x + 0, y - 1), trace)) stack.append((h, (x + 0, y + 1), trace)) else: assert False print(part1, part2)