diff --git a/README.md b/README.md index 52540da0..f3aaf501 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,4 @@ Development occurs in language-specific directories: |[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.py](py/aoc2024/day5.py)|[day5.rs](rs/src/day5.rs)| |[Day6.hs](hs/src/Day6.hs)|[Day6.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day6.kt)|[day6.py](py/aoc2024/day6.py)|[day6.rs](rs/src/day6.rs)| -|[Day7.hs](hs/src/Day7.hs)|[Day7.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day7.kt)||| +|[Day7.hs](hs/src/Day7.hs)|[Day7.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day7.kt)|[day7.py](py/aoc2024/day7.py)|| diff --git a/py/aoc2024/day7.py b/py/aoc2024/day7.py new file mode 100644 index 00000000..b087953f --- /dev/null +++ b/py/aoc2024/day7.py @@ -0,0 +1,76 @@ +""" +Day 7: +""" + +from typing import Callable, Iterable + +SAMPLE_INPUT = """ +190: 10 19 +3267: 81 40 27 +83: 17 5 +156: 15 6 +7290: 6 8 6 15 +161011: 16 10 13 +192: 17 8 14 +21037: 9 7 18 13 +292: 11 6 16 20 +""" + + +def _solve(data: str, op: Callable[[int, int], Iterable[int]]) -> int: + total = 0 + for line in filter(None, data.splitlines()): + lhs, rhs = line.split(":", maxsplit=1) + lhs, rhs = int(lhs), [int(value) for value in rhs.split()] + + def ok(x, remaining): + y = remaining[-1] + return ( + x == y + if len(remaining) == 1 + else any(ok(z, remaining[:-1]) for z in op(x, y)) + ) + + if ok(lhs, rhs): + total += lhs + return total + + +def part1(data: str) -> int: + """ + >>> part1(SAMPLE_INPUT) + 3749 + """ + + def op(x, y): + values = [] + if x >= y: + values.append(x - y) + if not x % y: + values.append(x // y) + return values + + return _solve(data, op) + + +def part2(data: str) -> int: + """ + >>> part2(SAMPLE_INPUT) + 11387 + """ + + def op(x, y): + values = [] + if x >= y: + values.append(x - y) + if not x % y: + values.append(x // y) + x, y = str(x), str(y) + if x.endswith(y) and len(x) > len(y): + values.append(int(x[: -len(y)])) + return values + + return _solve(data, op) + + +parts = (part1, part2) diff --git a/py/pyproject.toml b/py/pyproject.toml index 49a0b1a4..baa714a9 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -30,6 +30,7 @@ day3 = "aoc2024.day3:parts" day4 = "aoc2024.day4:parts" day5 = "aoc2024.day5:parts" day6 = "aoc2024.day6:parts" +day7 = "aoc2024.day7:parts" [build-system] requires = ["poetry-core"]