def move(data: list[list[str]], current_pos: tuple[int, int], current_order: str, movement_dict: dict[str, tuple[int, int]]) -> tuple[int, int]: assert data[current_pos[0]][current_pos[1]] == "@" direction = movement_dict[current_order] can_move = True steps = 0 while True: steps += 1 current_tile = data[current_pos[0] + direction[0] * steps][current_pos[1] + direction[1] * steps] if current_tile == "#": can_move = False break elif current_tile == ".": break if can_move: data[current_pos[0]][current_pos[1]] = "." if steps > 1: data[current_pos[0] + direction[0] * steps][current_pos[1] + direction[1] * steps] = "O" current_pos = (current_pos[0] + direction[0], current_pos[1] + direction[1]) data[current_pos[0]][current_pos[1]] = "@" return current_pos def calculate_gps_data(data: list[list[str]]): result = 0 for row_pos, row in enumerate(data): for col_pos, char in enumerate(row): if char == "O": result += row_pos * 100 + col_pos return result movement_dirs = { "<": (0, -1), "v": (1, 0), "^": (-1, 0), ">": (0, 1) } map_data = [] movement_data = "" with open("input") as f: reading_movement = False for line in f: line = line.strip() if reading_movement: movement_data += line else: if line == "": reading_movement = True else: map_data.append(list(line)) for row_idx, row in enumerate(map_data): for col_idx, char in enumerate(row): if char == "@": robot_row = row_idx robot_col = col_idx break else: continue break new_pos = (robot_row, robot_col) for order in movement_data: new_pos = move(map_data,new_pos, order, movement_dirs) for line in map_data: print("".join(line)) print(calculate_gps_data(map_data))