Spaces:
Running
Running
with open("input.txt") as f: | |
data = f.readlines() | |
def check_rule(pages: list[str], rule): | |
page2idx = {p: idx for idx, p in enumerate(pages)} | |
r0, r1 = rule | |
idx0 = page2idx.get(r0) | |
idx1 = page2idx.get(r1) | |
if idx0 is None or idx1 is None: | |
return True # "pass" | |
return idx0 < idx1 | |
def check_rules(pages, rules): | |
for rule in rules: | |
passes = check_rule(pages, rule) | |
if not passes: | |
return False | |
return True | |
rules = [] | |
page_numbers = [] | |
for line in data: | |
line = line.strip("\n") | |
if "|" in line: | |
r1, r2 = [int(r) for r in line.split("|")] | |
rules.append((r1, r2)) | |
elif len(line) > 0: | |
page_numbers.append([int(r) for r in line.split(",")]) | |
total = 0 | |
for pages in page_numbers: | |
passes = check_rules(pages, rules) | |
if passes: | |
mid_idx = len(pages) // 2 | |
total += pages[mid_idx] | |
print(total) | |
## Part 2 | |
def return_failing_rule(pages, rules): | |
for rule in rules: | |
passes = check_rule(pages, rule) | |
if not passes: | |
return rule | |
return None | |
def update_pages(pages, failed_rule): | |
"Swap the pages given the failed rule" | |
page2idx = {p: idx for idx, p in enumerate(pages)} | |
r0, r1 = failed_rule | |
idx0 = page2idx.get(r0) | |
idx1 = page2idx.get(r1) | |
new_pages = pages.copy() | |
new_pages[idx0] = r1 | |
new_pages[idx1] = r0 | |
return new_pages | |
def fix_pages(pages, rules): | |
failed_rule = return_failing_rule(pages, rules) | |
while failed_rule: | |
pages = update_pages(pages, failed_rule) | |
failed_rule = return_failing_rule(pages, rules) | |
return pages | |
total = 0 | |
for pages in page_numbers: | |
passes = check_rules(pages, rules) | |
if not passes: | |
new_pages = fix_pages(pages, rules) | |
mid_idx = len(pages) // 2 | |
total += new_pages[mid_idx] | |
print(total) | |