@@ -36,24 +36,6 @@ fn parse_input<'a>(input: &'a str) -> impl Iterator<Item = Secret> + 'a {
3636 . map ( |l| l. parse :: < Secret > ( ) . unwrap ( ) )
3737}
3838
39- #[ memoize]
40- fn gen_all_seq ( ) -> Vec < u32 > {
41- ( -9 ..9 )
42- . flat_map ( |a| {
43- ( -9 ..9 ) . flat_map ( move |b| {
44- ( -9 ..9 ) . flat_map ( move |c| {
45- ( -9 ..9 ) . map ( move |d| {
46- ( diff_to_seq_part ( a) << 24 )
47- | ( diff_to_seq_part ( b) << 16 )
48- | ( diff_to_seq_part ( c) << 8 )
49- | diff_to_seq_part ( d)
50- } )
51- } )
52- } )
53- } )
54- . collect ( )
55- }
56-
5739pub fn part_one ( input : & str ) -> Option < u64 > {
5840 let seeds = parse_input ( input) . collect :: < Vec < _ > > ( ) ;
5941 let res = seeds
@@ -64,38 +46,61 @@ pub fn part_one(input: &str) -> Option<u64> {
6446 Some ( res)
6547}
6648
49+ const SEQ_PART_SIZE : usize = 5 ;
50+ const SEQ_MASK_4 : u32 = ( 1 << ( SEQ_PART_SIZE * 4 ) ) - 1 ;
51+ const SEQ_MASK_1 : u32 = ( 1 << SEQ_PART_SIZE ) - 1 ;
52+
6753type Seq = u32 ;
6854type SeqDiff = i8 ;
6955
7056#[ inline]
7157fn diff_to_seq_part ( diff : SeqDiff ) -> Seq {
72- ( diff as Seq ) & 0xFF
58+ ( diff as Seq & SEQ_MASK_1 ) as Seq
7359}
7460
7561#[ inline]
76- fn push_seq ( seq : Seq , diff : SeqDiff ) -> u32 {
62+ fn push_seq ( seq : Seq , diff : SeqDiff ) -> Seq {
7763 // we are working mod 10 so + 10 is fine
78- ( seq << 8 ) | diff_to_seq_part ( diff)
64+ ( ( seq << SEQ_PART_SIZE ) | diff_to_seq_part ( diff) ) & SEQ_MASK_4
65+ }
66+
67+ #[ memoize]
68+ fn gen_all_seq ( ) -> Vec < Seq > {
69+ ( -9 ..9 )
70+ . flat_map ( |a| {
71+ ( -9 ..9 ) . flat_map ( move |b| {
72+ ( -9 ..9 ) . flat_map ( move |c| {
73+ ( -9 ..9 ) . map ( move |d| {
74+ ( diff_to_seq_part ( a) << ( SEQ_PART_SIZE * 3 ) )
75+ | ( diff_to_seq_part ( b) << ( SEQ_PART_SIZE * 2 ) )
76+ | ( diff_to_seq_part ( c) << SEQ_PART_SIZE )
77+ | diff_to_seq_part ( d)
78+ } )
79+ } )
80+ } )
81+ } )
82+ . collect ( )
7983}
8084
8185pub fn part_two ( input : & str ) -> Option < i32 > {
8286 let seeds = parse_input ( input) . collect :: < Vec < _ > > ( ) ;
83- let seeds_prices = seeds
87+ let seeds_seq_map = seeds
8488 . par_iter ( )
8589 . map ( |seed| {
86- let mut prices = [ ( 0_i8 , 0_u32 ) ; 2000 ] ;
87-
90+ let mut seq_map = vec ! [ None ; 1 << ( SEQ_PART_SIZE * 4 ) ] ;
8891 let mut prev_price = 0 ;
8992 let mut secret = * seed;
9093 let mut seq = 0 ;
91- for i in 0 ..2000 {
94+ for _ in 0 ..2000 {
9295 secret = next_secret ( secret) ;
9396 let new_price = ( secret % 10 ) as i8 ;
9497 seq = push_seq ( seq, new_price - prev_price) ;
95- prices[ i] = ( new_price, seq) ;
98+ if seq_map[ seq as usize ] == None {
99+ seq_map[ seq as usize ] = Some ( new_price as i8 ) ;
100+ }
96101 prev_price = new_price;
97102 }
98- prices
103+ seq_map
99104 } )
100105 . collect :: < Vec < _ > > ( ) ;
101106
@@ -104,20 +109,10 @@ pub fn part_two(input: &str) -> Option<i32> {
104109 let max_bananas = seq_to_test
105110 . par_iter ( )
106111 . map ( |& target_seq| {
107- let bananas = seeds_prices
112+ let bananas = seeds_seq_map
108113 . iter ( )
109- . map ( |& seed_data| {
110- let bananas = seed_data
111- . iter ( )
112- . skip ( 4 )
113- . find ( |& ( _, seq) | * seq == target_seq)
114- . map ( |( p, _) | * p)
115- . unwrap_or ( 0 ) ;
116-
117- bananas as i32
118- } )
114+ . map ( |seq_map| seq_map[ target_seq as usize ] . unwrap_or ( 0 ) as i32 )
119115 . sum ( ) ;
120-
121116 bananas
122117 } )
123118 . max ( ) ;
0 commit comments