@@ -148,6 +148,11 @@ pub fn part2(input: &[u8]) -> usize {
148
148
let upper = size * 10_000 ;
149
149
assert ! ( lower <= start && start < upper) ;
150
150
151
+ compute ( & digits, size, start, upper)
152
+ }
153
+
154
+ #[ cfg( not( feature = "simd" ) ) ]
155
+ fn compute ( digits : & [ usize ] , size : usize , start : usize , upper : usize ) -> usize {
151
156
let mut coefficients = [ 0 ; 8 ] ;
152
157
let mut result = [ 0 ; 8 ] ;
153
158
@@ -163,6 +168,30 @@ pub fn part2(input: &[u8]) -> usize {
163
168
result. fold_decimal ( )
164
169
}
165
170
171
+ #[ cfg( feature = "simd" ) ]
172
+ fn compute ( digits : & [ usize ] , size : usize , start : usize , upper : usize ) -> usize {
173
+ use std:: simd:: Mask ;
174
+ use std:: simd:: Simd ;
175
+
176
+ let mask: Mask < i32 , 8 > = Mask :: from_bitmask ( 1 ) ;
177
+ let tens: Simd < u32 , 8 > = Simd :: splat ( 10 ) ;
178
+
179
+ let mut coefficients: Simd < u32 , 8 > = Simd :: splat ( 0 ) ;
180
+ let mut result: Simd < u32 , 8 > = Simd :: splat ( 0 ) ;
181
+
182
+ for ( k, index) in ( start..upper) . enumerate ( ) {
183
+ coefficients = mask. select (
184
+ Simd :: splat ( binomial_mod_10 ( k + 99 , k) as u32 ) ,
185
+ coefficients. rotate_elements_right :: < 1 > ( ) ,
186
+ ) ;
187
+
188
+ let next = Simd :: splat ( digits[ index % size] as u32 ) ;
189
+ result += next * coefficients;
190
+ }
191
+
192
+ ( result % tens) . to_array ( ) . fold_decimal ( ) as usize
193
+ }
194
+
166
195
/// Computes C(n, k) % 2
167
196
///
168
197
/// This collapses to a special case of a product of only 4 possible values:
0 commit comments