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)