From 4b95a91485d56adeee0493b4b73f87868a05c282 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Sun, 22 Dec 2024 00:51:01 -0500 Subject: [PATCH] 2024: d22: ex2: add solution --- 2024/d22/ex2/ex2.py | 61 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100755 2024/d22/ex2/ex2.py diff --git a/2024/d22/ex2/ex2.py b/2024/d22/ex2/ex2.py new file mode 100755 index 0000000..2950de9 --- /dev/null +++ b/2024/d22/ex2/ex2.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +import functools +import itertools +import operator +import sys +from collections import Counter, deque +from collections.abc import Iterator + +Sequence = tuple[int, int, int, int] + + +def solve(input: str) -> int: + def monkey_hash(seed: int) -> int: + MASK = (1 << 24) - 1 + seed ^= seed << 6 + seed &= MASK + + seed ^= seed >> 5 + seed &= MASK + + seed ^= seed << 11 + seed &= MASK + + return seed + + def list_prices(seed: int) -> list[int]: + prices: list[int] = [seed % 10] + for _ in range(2000): + seed = monkey_hash(seed) + prices.append(seed % 10) + return prices + + def find_sequences(prices: list[int]) -> Counter[Sequence]: + # Adapted from an `itertools` recipe + def sliding_window() -> Iterator[tuple[int, ...]]: + iterator = iter(prices) + window = deque(itertools.islice(iterator, 5 - 1), maxlen=5) + for x in iterator: + window.append(x) + yield tuple(window) + + assert len(prices) == 2001 # Sanity check + sequences: Counter[Sequence] = Counter() + for i, (a, b, c, d, e) in enumerate(sliding_window(), start=4): + sequences.setdefault((b - a, c - b, d - c, e - d), prices[i]) + return sequences + + seeds = [int(n) for n in input.splitlines()] + prices = [list_prices(seed) for seed in seeds] + sequences = functools.reduce(operator.add, map(find_sequences, prices)) + return max(sequences.values()) + + +def main() -> None: + input = sys.stdin.read() + print(solve(input)) + + +if __name__ == "__main__": + main()