33import numpy
44from numpy .lib .stride_tricks import sliding_window_view
55
6- from . import SeparateRunner
6+ from . import CombinedRunner
77
88
99def advance (secrets : numpy .array ) -> numpy .array :
@@ -15,18 +15,9 @@ def advance(secrets: numpy.array) -> numpy.array:
1515 return new_secrets
1616
1717
18- class DayRunner (SeparateRunner ):
18+ class DayRunner (CombinedRunner ):
1919 @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 :
20+ def run_both (cls , input : str ) -> tuple [int , int ]:
3021 secrets = numpy .fromstring (input , dtype = int , sep = "\n " )
3122
3223 progression = [secrets ]
@@ -37,15 +28,14 @@ def part2(cls, input: str) -> int:
3728
3829 field = numpy .stack (progression , axis = - 1 ) % 10
3930 delta = field [:, 1 :] - field [:, :- 1 ]
31+ windows = sliding_window_view (delta , 4 , axis = 1 )
4032
4133 per_signal = defaultdict (int )
4234
43- for row_scores , row_deltas in zip (field , delta ):
44- unique , positions = numpy .unique (
45- sliding_window_view (row_deltas , 4 ), return_index = True , axis = 0
46- )
35+ for row_scores , row_deltas in zip (field , windows ):
36+ unique , positions = numpy .unique (row_deltas , return_index = True , axis = 0 )
4737
48- for key , index in zip (unique , positions ):
49- per_signal [tuple (key )] += row_scores [ index + 4 ]
38+ for key , bananas in zip (unique , row_scores [ positions + 4 ] ):
39+ per_signal [tuple (key )] += bananas
5040
51- return max (per_signal .values ())
41+ return secrets . sum (), max (per_signal .values ())
0 commit comments