Skip to content

Commit

Permalink
feat: add adv_2024_22
Browse files Browse the repository at this point in the history
  • Loading branch information
vil02 committed Dec 22, 2024
1 parent 7247e6d commit b2b4ed8
Show file tree
Hide file tree
Showing 4 changed files with 2,147 additions and 0 deletions.
70 changes: 70 additions & 0 deletions solutions/adv_2024_22.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import math
import functools


def _parse_input(in_str: str) -> list[int]:
return [int(_) for _ in in_str.splitlines()]


def _mix(val: int, secret: int) -> int:
return val ^ secret


def _prune(val: int) -> int:
return val % 16777216


def next_secret(secret: int) -> int:
res = secret * 64
secret = _prune(_mix(res, secret))
res = math.floor(secret / 32)
secret = _prune(_mix(res, secret))
res = secret * 2048
return _prune(_mix(res, secret))


@functools.cache
def _all_secrets(secret: int) -> list[int]:
res = [secret]
cur_val = secret
for _ in range(2000):
cur_val = next_secret(cur_val)
res.append(cur_val)
return res


def solve_a(in_str: str) -> int:
return sum(
_all_secrets(
_,
)[-1]
for _ in _parse_input(in_str)
)


def _prices(secret: int) -> list[int]:
return [_ % 10 for _ in _all_secrets(secret)]


def _changes(prices: list[int]) -> list[int]:
return [_n - _p for _n, _p in zip(prices[1:], prices)]


def _possible_prices(
prices: list[int], changes: list[int]
) -> dict[tuple[int, int, int, int], int]:
res = {}
for _ in range(len(changes) - 3):
pattern = (changes[_], changes[_ + 1], changes[_ + 2], changes[_ + 3])
if pattern not in res:
res[pattern] = prices[_ + 4]
return res


def solve_b(in_str: str) -> int:
results: dict[tuple[int, int, int, int], int] = {}
for _ in _parse_input(in_str):
prices = _prices(_)
for _k, _v in _possible_prices(prices, _changes(prices)).items():
results[_k] = results.get(_k, 0) + _v
return max(results.values())
29 changes: 29 additions & 0 deletions tests/test_adv_2024_22.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import pytest

import solutions.adv_2024_22 as sol
from . import test_utils as tu


@pytest.mark.parametrize(
("secret", "expected"),
[
(123, 15887950),
(15887950, 16495136),
(16495136, 527345),
(527345, 704524),
(704524, 1553684),
(1553684, 12683156),
(12683156, 11100544),
(11100544, 12249484),
(12249484, 7753432),
(7753432, 5908254),
],
)
def test_next_secret(secret: int, expected: int) -> None:
assert sol.next_secret(secret) == expected


_INPUTS = tu.get_inputs(22, {"small", "p"})

test_solve_a = _INPUTS.get_test(sol.solve_a, {"small": 37327623, "p": 17005483322})
test_solve_b = _INPUTS.get_test(sol.solve_b, {"p": 1910})
Loading

0 comments on commit b2b4ed8

Please sign in to comment.