def get_start(grid: list[str]) -> [int, int]: x, y = 0, 0 for row, line in enumerate(grid): if '^' in line: y = row break x = grid[y].find('^') return [x, y] def peek(grid: list[str], x: int, y: int) -> str: try: if y < 0 or x < 0: return '' return grid[y][x] except IndexError: return '' def rotate(vel: [int, int]) -> [int, int]: # going up? -> go right if vel == [0,-1]: return [1,0] # going right? -> go down elif vel == [1,0]: return [0,1] # going down? -> go left elif vel == [0,1]: return [-1,0] # goign left? -> go up elif vel == [-1,0]: return [0,-1] else: raise ValueError('brother wtf') def crawl(grid: list[str], x: int, y: int) -> set[(int, int)]: # non -unique set that we'll have to clean up visited = set() visited.add((x,y)) vel = [0,-1] while val := peek(grid, x+vel[0], y+vel[1]): # Record where we go print((x,y), 'vel ->', vel) if val == '.' or val == '^': x += vel[0] y += vel[1] visited.add((x,y)) # Don't record the walls if val == '#': vel = rotate(vel) return visited if __name__ == '__main__': with open('input.data') as raw: grid = [ line.strip() for line in raw ] start_x, start_y = get_start(grid) print(len(grid), len(grid[0])) places = crawl(grid, start_x, start_y) print(len(places))