import aocd import collections def parse_rules(orders): """ Return a dictionary mapping page numbers to lists of page numbers For any given key, each page of the value must come after it """ rules = collections.defaultdict(list) for order in orders: k,v = order.split('|') rules[k].append(v) return rules def update_is_incorrect(update, rules): for n, page in enumerate(update): for prev_n, prev_page in enumerate(update[:n]): if prev_page in rules[page]: return (n, prev_n) return False def fix_update(update, rules): def insert_before(l, a, b): """ Mutate l with the bth element moved to just before the ath """ l.insert(a, l.pop(b)) while (indices := update_is_incorrect(update, rules)): insert_before(update, *indices) return int(update[len(update)//2]) def solve(data): orders, updates = data.split('\n\n') updates = (u.split(',') for u in updates.split('\n')) rules = parse_rules(orders.split('\n')) incorrect = (u for u in updates if update_is_incorrect(u, rules)) return sum(fix_update(u, rules) for u in incorrect) if __name__ == '__main__': print('Warning: This is horrifically slow but I do not feel like spending time on a sorting problem', file=__import__('sys').stderr) puz = aocd.models.Puzzle(year=2024, day=5) # data = puz.examples[0].input_data data = puz.input_data solution = solve(data) print(solution) aocd.submit(solution, year=2024, day=5, part='b')