From 12009ebb6a87a06212ea0269d78d101964f0265e Mon Sep 17 00:00:00 2001 From: Daniel Lin Date: Thu, 5 Dec 2024 05:49:33 -0500 Subject: [PATCH] Day 5: Print Queue --- README.md | 2 +- py/aoc2024/day5.py | 94 ++++++++++++++++++++++++++++++++++++++++++++++ py/pyproject.toml | 1 + 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 py/aoc2024/day5.py diff --git a/README.md b/README.md index b978bd1d..effe123f 100644 --- a/README.md +++ b/README.md @@ -9,4 +9,4 @@ Development occurs in language-specific directories: |[Day2.hs](hs/src/Day2.hs)|[Day2.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day2.kt)|[day2.py](py/aoc2024/day2.py)|[day2.rs](rs/src/day2.rs)| |[Day3.hs](hs/src/Day3.hs)|[Day3.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day3.kt)|[day3.py](py/aoc2024/day3.py)|[day3.rs](rs/src/day3.rs)| |[Day4.hs](hs/src/Day4.hs)|[Day4.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day4.kt)|[day4.py](py/aoc2024/day4.py)|[day4.rs](rs/src/day4.rs)| -|[Day5.hs](hs/src/Day5.hs)|[Day5.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day5.kt)||| +|[Day5.hs](hs/src/Day5.hs)|[Day5.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day5.kt)|[day5.py](py/aoc2024/day5.py)|| diff --git a/py/aoc2024/day5.py b/py/aoc2024/day5.py new file mode 100644 index 00000000..d204d582 --- /dev/null +++ b/py/aoc2024/day5.py @@ -0,0 +1,94 @@ +""" +Day 5: Print Queue +""" + +from typing import Callable, Iterable, List, Set, Tuple + +SAMPLE_INPUT = """ +47|53 +97|13 +97|61 +97|47 +75|29 +61|13 +75|53 +29|13 +97|29 +53|29 +61|53 +97|53 +61|29 +47|13 +75|47 +97|75 +47|61 +75|61 +47|29 +75|13 +53|13 + +75,47,61,53,29 +97,61,53,29,13 +75,29,13 +75,97,47,61,53 +61,13,29 +97,13,75,29,47 +""" + + +def _parse(data: str) -> Tuple[Set[Tuple[int, int]], List[List[int]]]: + (deps, updates) = data.split("\n\n") + deps = { + tuple(int(page) for page in line.split("|")) + for line in deps.splitlines() + if line + } + updates = [ + [int(page) for page in line.split(",")] for line in updates.splitlines() if line + ] + return deps, updates + + +def part1(data: str) -> int: + """ + >>> part1(SAMPLE_INPUT) + 143 + """ + deps, updates = _parse(data) + return sum( + pages[len(pages) // 2] + for pages in updates + if all((y, x) not in deps for i, x in enumerate(pages) for y in pages[i + 1 :]) + ) + + +def part2(data: str) -> int: + """ + >>> part2(SAMPLE_INPUT) + 123 + """ + deps, updates = _parse(data) + return sum( + sorted_pages[len(pages) // 2] + for pages in updates + if pages + != (sorted_pages := _partial_sorted(pages, lambda x, y: (y, x) not in deps)) + ) + + +def _partial_sorted[T](iterable: Iterable[T], ok: Callable[[T, T], bool]) -> List[T]: + output = list(iterable) + i = 0 + while i < len(output): + x = output[i] + for j in range(i + 1, len(output)): + y = output[j] + if not ok(x, y): + output[i], output[j] = y, x + break + else: + i += 1 + return output + + +parts = (part1, part2) diff --git a/py/pyproject.toml b/py/pyproject.toml index c2177801..c4e8a04e 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -28,6 +28,7 @@ day1 = "aoc2024.day1:parts" day2 = "aoc2024.day2:parts" day3 = "aoc2024.day3:parts" day4 = "aoc2024.day4:parts" +day5 = "aoc2024.day5:parts" [build-system] requires = ["poetry-core"]