From 023807a70112346efb6962d02945990319f09a63 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Wed, 11 Dec 2024 08:51:32 +0100 Subject: [PATCH] Implement 2024 day 11 --- 2024/src/aoc/days/day11.py | 50 ++++++++++++++++++++++++++++++++++++++ 2024/tests/test_day11.py | 7 ++++++ 2 files changed, 57 insertions(+) create mode 100644 2024/src/aoc/days/day11.py create mode 100644 2024/tests/test_day11.py diff --git a/2024/src/aoc/days/day11.py b/2024/src/aoc/days/day11.py new file mode 100644 index 0000000..cd0cb6c --- /dev/null +++ b/2024/src/aoc/days/day11.py @@ -0,0 +1,50 @@ +import functools +from collections import defaultdict + +from . import CombinedRunner + + +@functools.cache +def blink_num(num: int) -> tuple[int, ...]: + if num == 0: + return (1,) + + num_str = str(num) + num_len = len(num_str) + + if num_len % 2 == 0: + half = num_len // 2 + return (int(num_str[:half]), int(num_str[half:])) + + return (num * 2024,) + + +def step(nums: dict[int, int]) -> dict[int, int]: + result = defaultdict(int) + + for num, count in nums.items(): + for transformed in blink_num(num): + result[transformed] += count + + return result + + +class DayRunner(CombinedRunner): + @classmethod + def run_both(cls, input: str) -> tuple[int, int]: + nums = [int(val) for val in input.strip().split(" ")] + + counts = defaultdict(int) + + for num in nums: + counts[num] += 1 + + for _ in range(25): + counts = step(counts) + + part1 = sum(counts.values()) + + for _ in range(50): + counts = step(counts) + + return part1, sum(counts.values()) diff --git a/2024/tests/test_day11.py b/2024/tests/test_day11.py new file mode 100644 index 0000000..c839c1f --- /dev/null +++ b/2024/tests/test_day11.py @@ -0,0 +1,7 @@ +from aoc.days.day11 import DayRunner + +SAMPLE = "125 17" + + +def test_sample_part1() -> None: + assert DayRunner.part1(SAMPLE) == 55312