Spaces:
Running
Running
File size: 3,008 Bytes
a4da721 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
from collections import deque
def parse_input(file):
with open(file, 'r') as f:
grid = [list(line.strip()) for line in f]
start = end = None
for r, row in enumerate(grid):
for c, val in enumerate(row):
if val == 'S':
start = (r, c)
elif val == 'E':
end = (r, c)
return grid, start, end
def bfs(grid, start, end, max_cheat_time):
rows, cols = len(grid), len(grid[0])
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
queue = deque([(start[0], start[1], 0, 0)]) # (row, col, time, cheat_time)
visited = set()
visited.add((start[0], start[1], 0)) # (row, col, cheat_time)
min_time = float('inf')
cheats = []
while queue:
r, c, time, cheat_time = queue.popleft()
if (r, c) == end:
if time < min_time:
min_time = time
continue
for dr, dc in directions:
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols:
if grid[nr][nc] == '.' or grid[nr][nc] == 'E':
if (nr, nc, cheat_time) not in visited:
visited.add((nr, nc, cheat_time))
queue.append((nr, nc, time + 1, cheat_time))
elif grid[nr][nc] == '#' and cheat_time < max_cheat_time:
if (nr, nc, cheat_time + 1) not in visited:
visited.add((nr, nc, cheat_time + 1))
queue.append((nr, nc, time + 1, cheat_time + 1))
return min_time
def count_cheats(grid, start, end, max_cheat_time, baseline_time):
rows, cols = len(grid), len(grid[0])
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
queue = deque([(start[0], start[1], 0, 0)]) # (row, col, time, cheat_time)
visited = set()
visited.add((start[0], start[1], 0)) # (row, col, cheat_time)
cheat_savings = []
while queue:
r, c, time, cheat_time = queue.popleft()
if (r, c) == end:
savings = baseline_time - time
if savings >= 100:
cheat_savings.append(savings)
continue
for dr, dc in directions:
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols:
if grid[nr][nc] == '.' or grid[nr][nc] == 'E':
if (nr, nc, cheat_time) not in visited:
visited.add((nr, nc, cheat_time))
queue.append((nr, nc, time + 1, cheat_time))
elif grid[nr][nc] == '#' and cheat_time < max_cheat_time:
if (nr, nc, cheat_time + 1) not in visited:
visited.add((nr, nc, cheat_time + 1))
queue.append((nr, nc, time + 1, cheat_time + 1))
return len(cheat_savings)
file = "input.txt"
grid, start, end = parse_input(file)
baseline_time = bfs(grid, start, end, 0)
cheat_count = count_cheats(grid, start, end, 20, baseline_time)
print(cheat_count) |