advent24-llm / day16 /solution_claude-3-5-sonnet-20241022.py
jerpint's picture
Add solution files
a4da721
from collections import defaultdict
from heapq import heappush, heappop
def parse_maze(filename):
with open(filename) as f:
maze = [list(line.strip()) for line in f]
# Find start and end
start = end = None
for y in range(len(maze)):
for x in range(len(maze[0])):
if maze[y][x] == 'S':
start = (x, y)
elif maze[y][x] == 'E':
end = (x, y)
return maze, start, end
def get_neighbors(pos, direction, maze):
x, y = pos
moves = []
# Forward
dx, dy = direction
new_x, new_y = x + dx, y + dy
if 0 <= new_x < len(maze[0]) and 0 <= new_y < len(maze) and maze[new_y][new_x] != '#':
moves.append(((new_x, new_y), direction, 1))
# Turn left
new_dir = (-dy, dx)
moves.append((pos, new_dir, 1000))
# Turn right
new_dir = (dy, -dx)
moves.append((pos, new_dir, 1000))
return moves
def find_min_score(maze, start, end):
# Direction: (dx, dy)
# Start facing east
initial_dir = (1, 0)
# Priority queue: (score, position, direction)
queue = [(0, start, initial_dir)]
seen = set()
scores = defaultdict(lambda: float('inf'))
scores[(start, initial_dir)] = 0
while queue:
score, pos, direction = heappop(queue)
if pos == end:
return score
if (pos, direction) in seen:
continue
seen.add((pos, direction))
for new_pos, new_dir, cost in get_neighbors(pos, direction, maze):
new_score = score + cost
if new_score < scores[(new_pos, new_dir)]:
scores[(new_pos, new_dir)] = new_score
heappush(queue, (new_score, new_pos, new_dir))
return float('inf')
def find_optimal_paths(maze, start, end, min_score):
optimal_tiles = set()
initial_dir = (1, 0)
def dfs(pos, direction, score, path):
if score > min_score:
return
if pos == end and score == min_score:
optimal_tiles.update(path)
return
for new_pos, new_dir, cost in get_neighbors(pos, direction, maze):
if new_pos not in path or new_pos == end: # Allow revisiting end
dfs(new_pos, new_dir, score + cost, path | {new_pos})
dfs(start, initial_dir, 0, {start})
return len(optimal_tiles)
# Solve both parts
maze, start, end = parse_maze("input.txt")
min_score = find_min_score(maze, start, end)
print(str(min_score))
optimal_tiles = find_optimal_paths(maze, start, end, min_score)
print(str(optimal_tiles))