From a5ecc18f1098c5031be6e4dda088fcf004f38cd7 Mon Sep 17 00:00:00 2001 From: Holly McFarland Date: Fri, 6 Dec 2024 18:05:54 -0500 Subject: [PATCH] day 5 --- day_05/part_a.py | 44 +++++++++++++++++++++++++++++++++++++ day_05/part_b.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 day_05/part_a.py create mode 100644 day_05/part_b.py diff --git a/day_05/part_a.py b/day_05/part_a.py new file mode 100644 index 0000000..0643afe --- /dev/null +++ b/day_05/part_a.py @@ -0,0 +1,44 @@ +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 verify_update(update, rules): + """ + Ensure that an update is valid using an O(n^2) approach that will + bite me in the ass in part B somehow + """ + update = update.split(',') + for n, page in enumerate(update): + for prev_page in update[:n]: + if prev_page in rules[page]: + return 0 + return int(update[len(update)//2]) + + +def solve(data): + orders, updates = data.split('\n\n') + rules = parse_rules(orders.split('\n')) + return sum(verify_update(u, rules) for u in updates.split('\n')) + +if __name__ == '__main__': + 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='a') \ No newline at end of file diff --git a/day_05/part_b.py b/day_05/part_b.py new file mode 100644 index 0000000..e541311 --- /dev/null +++ b/day_05/part_b.py @@ -0,0 +1,56 @@ +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') \ No newline at end of file