| 
1 |  | -use memoize::memoize;  | 
 | 1 | +use bitvec::bitvec;  | 
2 | 2 | use rayon::iter::{IntoParallelRefIterator, ParallelIterator};  | 
3 | 3 | 
 
  | 
4 | 4 | advent_of_code::solution!(22);  | 
@@ -53,71 +53,44 @@ const SEQ_MASK_1: u32 = (1 << SEQ_PART_SIZE) - 1;  | 
53 | 53 | type Seq = u32;  | 
54 | 54 | type SeqDiff = i8;  | 
55 | 55 | 
 
  | 
56 |  | -#[inline]  | 
57 |  | -fn diff_to_seq_part(diff: SeqDiff) -> Seq {  | 
58 |  | -    (diff as Seq & SEQ_MASK_1) as Seq  | 
59 |  | -}  | 
60 |  | - | 
61 | 56 | #[inline]  | 
62 | 57 | fn push_seq(seq: Seq, diff: SeqDiff) -> Seq {  | 
63 | 58 |     // we are working mod 10 so + 10 is fine  | 
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()  | 
 | 59 | +    ((seq << SEQ_PART_SIZE) | (diff as Seq & SEQ_MASK_1)) & SEQ_MASK_4  | 
83 | 60 | }  | 
84 | 61 | 
 
  | 
85 | 62 | pub fn part_two(input: &str) -> Option<i32> {  | 
86 | 63 |     let seeds = parse_input(input).collect::<Vec<_>>();  | 
87 |  | -    let seeds_seq_map = seeds  | 
88 |  | -        .par_iter()  | 
89 |  | -        .map(|seed| {  | 
90 |  | -            let mut seq_map = vec![None; 1 << (SEQ_PART_SIZE * 4)];  | 
91 |  | -            let mut prev_price = 0;  | 
92 |  | -            let mut secret = *seed;  | 
93 |  | -            let mut seq = 0;  | 
94 |  | -            for _ in 0..2000 {  | 
95 |  | -                secret = next_secret(secret);  | 
96 |  | -                let new_price = (secret % 10) as i8;  | 
97 |  | -                seq = push_seq(seq, new_price - prev_price);  | 
98 |  | -                if seq_map[seq as usize] == None {  | 
99 |  | -                    seq_map[seq as usize] = Some(new_price as i8);  | 
100 |  | -                }  | 
101 |  | -                prev_price = new_price;  | 
 | 64 | + | 
 | 65 | +    let mut seq_bananas = vec![0; 1 << (SEQ_PART_SIZE * 4)];  | 
 | 66 | + | 
 | 67 | +    seeds.iter().for_each(|seed| {  | 
 | 68 | +        let mut seen = bitvec![0; 1 << (SEQ_PART_SIZE * 4)];  | 
 | 69 | + | 
 | 70 | +        let mut prev_price = 0;  | 
 | 71 | +        let mut secret = *seed;  | 
 | 72 | +        let mut seq = 0;  | 
 | 73 | + | 
 | 74 | +        for i in 0..2000 {  | 
 | 75 | +            secret = next_secret(secret);  | 
 | 76 | +            let new_price = (secret % 10) as i8;  | 
 | 77 | +            seq = push_seq(seq, new_price - prev_price);  | 
 | 78 | +            prev_price = new_price;  | 
 | 79 | + | 
 | 80 | +            if i < 4 {  | 
 | 81 | +                continue;  | 
 | 82 | +            }  | 
 | 83 | +            if seen[seq as usize] {  | 
 | 84 | +                continue;  | 
102 | 85 |             }  | 
103 |  | -            seq_map  | 
104 |  | -        })  | 
105 |  | -        .collect::<Vec<_>>();  | 
106 | 86 | 
 
  | 
107 |  | -    let seq_to_test = gen_all_seq();  | 
 | 87 | +            seen.set(seq as usize, true);  | 
 | 88 | +            seq_bananas[seq as usize] += new_price as i32;  | 
 | 89 | +        }  | 
 | 90 | +    });  | 
108 | 91 | 
 
  | 
109 |  | -    let max_bananas = seq_to_test  | 
110 |  | -        .par_iter()  | 
111 |  | -        .map(|&target_seq| {  | 
112 |  | -            let bananas = seeds_seq_map  | 
113 |  | -                .iter()  | 
114 |  | -                .map(|seq_map| seq_map[target_seq as usize].unwrap_or(0) as i32)  | 
115 |  | -                .sum();  | 
116 |  | -            bananas  | 
117 |  | -        })  | 
118 |  | -        .max();  | 
119 |  | - | 
120 |  | -    Some(max_bananas.unwrap())  | 
 | 92 | +    let max_bananas = seq_bananas.into_iter().max().unwrap();  | 
 | 93 | +    Some(max_bananas)  | 
121 | 94 | }  | 
122 | 95 | 
 
  | 
123 | 96 | #[cfg(test)]  | 
 | 
0 commit comments