Spaces:
Running
Running
from collections import deque | |
def parse_input(file): | |
with open(file, 'r') as f: | |
maze = [list(line.strip()) for line in f] | |
return maze | |
def find_start_end(maze): | |
start = end = None | |
for r, row in enumerate(maze): | |
for c, val in enumerate(row): | |
if val == 'S': | |
start = (r, c) | |
elif val == 'E': | |
end = (r, c) | |
return start, end | |
def get_neighbors(pos, direction, maze): | |
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] # East, South, West, North | |
r, c = pos | |
neighbors = [] | |
# Move forward | |
dr, dc = directions[direction] | |
if maze[r + dr][c + dc] != '#': | |
neighbors.append(((r + dr, c + dc), direction, 1)) # 1 point for moving forward | |
# Turn clockwise | |
neighbors.append((pos, (direction + 1) % 4, 1000)) # 1000 points for turning | |
# Turn counterclockwise | |
neighbors.append((pos, (direction - 1) % 4, 1000)) # 1000 points for turning | |
return neighbors | |
def find_best_paths(maze, start, end): | |
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] # East, South, West, North | |
start_direction = 0 # Start facing East | |
queue = deque([(start, start_direction, 0)]) # (position, direction, score) | |
visited = set() | |
best_score = float('inf') | |
best_paths = set() | |
while queue: | |
pos, direction, score = queue.popleft() | |
if (pos, direction) in visited: | |
continue | |
visited.add((pos, direction)) | |
if pos == end: | |
if score < best_score: | |
best_score = score | |
best_paths = {pos} | |
elif score == best_score: | |
best_paths.add(pos) | |
continue | |
for neighbor, new_direction, cost in get_neighbors(pos, direction, maze): | |
new_score = score + cost | |
if new_score <= best_score: | |
queue.append((neighbor, new_direction, new_score)) | |
if new_score == best_score: | |
best_paths.add(neighbor) | |
return best_paths | |
def count_best_path_tiles(maze, best_paths): | |
count = 0 | |
for r, row in enumerate(maze): | |
for c, val in enumerate(row): | |
if (r, c) in best_paths and val != '#': | |
count += 1 | |
return count | |
def main(): | |
file = "input.txt" | |
maze = parse_input(file) | |
start, end = find_start_end(maze) | |
best_paths = find_best_paths(maze, start, end) | |
result = count_best_path_tiles(maze, best_paths) | |
print(result) | |
main() |