def parse_input(file): with open(file, 'r') as f: grid = [list(line.strip()) for line in f.readlines()] return grid def find_guard_start(grid): directions = {'^': (0, -1), '>': (1, 0), 'v': (0, 1), '<': (-1, 0)} for y, row in enumerate(grid): for x, cell in enumerate(row): if cell in directions: return (x, y), directions[cell] return None, None def turn_right(direction): right_turns = {(0, -1): (1, 0), (1, 0): (0, 1), (0, 1): (-1, 0), (-1, 0): (0, -1)} return right_turns[direction] def move(position, direction): return position[0] + direction[0], position[1] + direction[1] def is_within_bounds(position, grid): x, y = position return 0 <= x < len(grid[0]) and 0 <= y < len(grid) def simulate_guard(grid): start_pos, direction = find_guard_start(grid) visited = set() position = start_pos while is_within_bounds(position, grid): visited.add(position) next_position = move(position, direction) if is_within_bounds(next_position, grid) and grid[next_position[1]][next_position[0]] == '#': direction = turn_right(direction) else: position = next_position return visited def simulate_with_obstruction(grid, obstruction_pos): start_pos, direction = find_guard_start(grid) visited = set() position = start_pos direction_map = {(-1, 0): '<', (0, -1): '^', (1, 0): '>', (0, 1): 'v'} while is_within_bounds(position, grid): if position == obstruction_pos: return False # Obstruction is here, can't move if (position, direction) in visited: return True # Loop detected visited.add((position, direction)) next_position = move(position, direction) if is_within_bounds(next_position, grid) and (grid[next_position[1]][next_position[0]] == '#' or next_position == obstruction_pos): direction = turn_right(direction) else: position = next_position return False def find_loop_positions(grid): loop_positions = 0 for y, row in enumerate(grid): for x, cell in enumerate(row): if cell == '.' and (x, y) != find_guard_start(grid)[0]: if simulate_with_obstruction(grid, (x, y)): loop_positions += 1 return loop_positions file = "input.txt" grid = parse_input(file) # Part 1 visited_positions = simulate_guard(grid) print(len(visited_positions)) # Part 2 loop_positions = find_loop_positions(grid) print(loop_positions)