Skip to content

Commit 230b4ae

Browse files
committed
Implement 2024 day 22
1 parent be2244e commit 230b4ae

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed

2024/src/aoc/days/day22.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from collections import defaultdict
2+
3+
import numpy
4+
from numpy.lib.stride_tricks import sliding_window_view
5+
6+
from . import SeparateRunner
7+
8+
9+
def advance(secrets: numpy.array) -> numpy.array:
10+
new_secrets = (secrets ^ (secrets << 6)) & 0xFFFFFF
11+
new_secrets ^= new_secrets >> 5
12+
new_secrets ^= new_secrets << 11
13+
new_secrets &= 0xFFFFFF
14+
15+
return new_secrets
16+
17+
18+
class DayRunner(SeparateRunner):
19+
@classmethod
20+
def part1(cls, input: str) -> int:
21+
secrets = numpy.fromstring(input, dtype=int, sep="\n")
22+
23+
for _ in range(2000):
24+
secrets = advance(secrets)
25+
26+
return secrets.sum()
27+
28+
@classmethod
29+
def part2(cls, input: str) -> int:
30+
secrets = numpy.fromstring(input, dtype=int, sep="\n")
31+
32+
progression = [secrets]
33+
34+
for _ in range(2000):
35+
secrets = advance(secrets)
36+
progression.append(secrets)
37+
38+
field = numpy.stack(progression, axis=-1) % 10
39+
delta = field[:, 1:] - field[:, :-1]
40+
41+
per_signal = defaultdict(int)
42+
43+
for row_scores, row_deltas in zip(field, delta):
44+
seen = set()
45+
46+
for window, price in zip(
47+
sliding_window_view(row_deltas, 4), row_scores[4:]
48+
):
49+
key = tuple(window)
50+
if key not in seen:
51+
seen.add(key)
52+
per_signal[key] += price
53+
54+
return max(per_signal.values())

2024/tests/samples/22.1.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1
2+
10
3+
100
4+
2024

2024/tests/samples/22.2.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1
2+
2
3+
3
4+
2024

2024/tests/test_day22.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from aoc.days.day22 import DayRunner
2+
3+
from . import get_data
4+
5+
6+
def test_sample_part1() -> None:
7+
assert DayRunner.part1(get_data(22, 1)) == 37327623
8+
9+
10+
def test_sample_part2() -> None:
11+
assert DayRunner.part2(get_data(22, 2)) == 23

0 commit comments

Comments
 (0)