advent24-llm / day05 /solution_claude-3-5-sonnet-20241022.py
jerpint's picture
Add solution files
a4da721
from collections import defaultdict
import copy
def parse_input(filename):
rules = []
updates = []
with open(filename) as f:
lines = f.read().strip().split('\n')
# Find the empty line that separates rules and updates
separator = lines.index('')
# Parse rules
for line in lines[:separator]:
x, y = map(int, line.split('|'))
rules.append((x, y))
# Parse updates
for line in lines[separator+1:]:
update = list(map(int, line.split(',')))
updates.append(update)
return rules, updates
def build_graph(rules):
# Build adjacency list representation
graph = defaultdict(list)
for x, y in rules:
graph[x].append(y)
return graph
def is_valid_order(nums, graph):
# Check if current order satisfies all rules
num_set = set(nums)
for i, num in enumerate(nums):
for next_num in graph[num]:
if next_num in num_set:
# If there's a rule num->next_num, check if next_num appears after num
next_pos = nums.index(next_num)
if next_pos < i:
return False
return True
def topological_sort(nums, graph):
# Create a graph only with the numbers in the update
num_set = set(nums)
local_graph = defaultdict(list)
in_degree = defaultdict(int)
# Initialize in-degree for all numbers
for num in nums:
in_degree[num] = 0
# Build local graph and calculate in-degrees
for num in nums:
for next_num in graph[num]:
if next_num in num_set:
local_graph[num].append(next_num)
in_degree[next_num] += 1
# Find all nodes with in-degree 0
queue = [num for num in nums if in_degree[num] == 0]
result = []
while queue:
current = queue.pop(0)
result.append(current)
for next_num in local_graph[current]:
in_degree[next_num] -= 1
if in_degree[next_num] == 0:
queue.append(next_num)
return result
def get_middle_number(nums):
return nums[len(nums)//2]
# Read and parse input
rules, updates = parse_input("input.txt")
graph = build_graph(rules)
# Part 1: Sum middle numbers of correctly ordered updates
valid_sum = 0
invalid_updates = []
for update in updates:
if is_valid_order(update, graph):
valid_sum += get_middle_number(update)
else:
invalid_updates.append(update)
print(str(valid_sum))
# Part 2: Sum middle numbers of corrected invalid updates
invalid_sum = 0
for update in invalid_updates:
sorted_update = topological_sort(update, graph)
invalid_sum += get_middle_number(sorted_update)
print(str(invalid_sum))