def read_map(file): with open(file, 'r') as f: return [list(map(int, line.strip())) for line in f] def find_trailheads(map_data): trailheads = [] for r in range(len(map_data)): for c in range(len(map_data[0])): if map_data[r][c] == 0: trailheads.append((r, c)) return trailheads def is_valid_move(map_data, r, c, current_height): return 0 <= r < len(map_data) and 0 <= c < len(map_data[0]) and map_data[r][c] == current_height + 1 def explore_trails(map_data, start): stack = [(start, [start])] reached_nines = set() distinct_paths = set() while stack: (r, c), path = stack.pop() current_height = map_data[r][c] if current_height == 9: reached_nines.add((r, c)) distinct_paths.add(tuple(path)) continue for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]: nr, nc = r + dr, c + dc if is_valid_move(map_data, nr, nc, current_height): stack.append(((nr, nc), path + [(nr, nc)])) return len(reached_nines), len(distinct_paths) def calculate_scores_and_ratings(map_data): trailheads = find_trailheads(map_data) total_score = 0 total_rating = 0 for trailhead in trailheads: score, rating = explore_trails(map_data, trailhead) total_score += score total_rating += rating return total_score, total_rating def main(): file = "input.txt" map_data = read_map(file) total_score, total_rating = calculate_scores_and_ratings(map_data) print(total_score) print(total_rating) main()