|
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