@@ -159,18 +159,32 @@ fn aos(start_num: u64, num_blinks: u64, cach: &mut HashMap<(u64, u64), u64>) ->
159159 let mut top = unsafe { stack[ stack_i] . assume_init_read ( ) } ;
160160 let top_i = stack_i;
161161
162- if let Some ( r) = cach. get ( & top. cach_entry ) {
163- if top. parrent_stone == usize:: MAX {
164- return * r;
165- }
166- unsafe { stack[ top. parrent_stone ] . assume_init_mut ( ) } . stones += r;
167- stack_i -= 1 ;
168- continue ;
169- }
170162 loop {
171- if top. blinks_left == 0 {
163+ if top. blinks_left == 1 {
172164 if top_i == stack_i {
173- let r = top. stones ;
165+ let r = top. stones
166+ + match top. num {
167+ 0 ..=9 => 0 ,
168+ 10 ..=99 => 1 ,
169+ 100 ..=999 => 0 ,
170+ 1000 ..=9999 => 1 ,
171+ 10000 ..=99999 => 0 ,
172+ 100000 ..=999999 => 1 ,
173+ 1000000 ..=9999999 => 0 ,
174+ 10000000 ..=99999999 => 1 ,
175+ 100000000 ..=999999999 => 0 ,
176+ 1000000000 ..=9999999999 => 1 ,
177+ 10000000000 ..=99999999999 => 0 ,
178+ 100000000000 ..=999999999999 => 1 ,
179+ 1000000000000 ..=9999999999999 => 0 ,
180+ 10000000000000 ..=99999999999999 => 1 ,
181+ 100000000000000 ..=999999999999999 => 0 ,
182+ 1000000000000000 ..=9999999999999999 => 1 ,
183+ 10000000000000000 ..=99999999999999999 => 0 ,
184+ 100000000000000000 ..=999999999999999999 => 1 ,
185+ 1000000000000000000 ..=9999999999999999999 => 0 ,
186+ 10000000000000000000 ..=u64:: MAX => 1 ,
187+ } ;
174188 cach. insert ( top. cach_entry , r) ;
175189
176190 if top. parrent_stone == usize:: MAX {
@@ -184,24 +198,76 @@ fn aos(start_num: u64, num_blinks: u64, cach: &mut HashMap<(u64, u64), u64>) ->
184198 break ;
185199 }
186200
187- if top. num == 0 {
188- top. num = 1 ;
189- } else if top. num . ilog10 ( ) % 2 == 1 {
190- let num_digits = top. num . ilog10 ( ) + 1 ;
191- let tens = 10u64 . pow ( num_digits / 2 ) ;
201+ let mut insert_stone = |new_num| {
202+ if let Some ( r) = cach. get ( & ( new_num, top. blinks_left - 1 ) ) {
203+ return * r;
204+ }
192205
193206 stack_i += 1 ;
194207 stack[ stack_i] . write ( Stack {
195208 stones : 1 ,
196- num : top . num % tens ,
209+ num : new_num ,
197210 blinks_left : top. blinks_left - 1 ,
198211 parrent_stone : top_i,
199- cach_entry : ( top . num % tens , top. blinks_left - 1 ) ,
212+ cach_entry : ( new_num , top. blinks_left - 1 ) ,
200213 } ) ;
201- top. num = top. num / tens;
202- } else {
203- top. num *= 2024 ;
214+ return 0 ;
204215 } ;
216+
217+ match top. num {
218+ 0 => top. num = 1 ,
219+ 1 ..=9 => top. num *= 2024 ,
220+ 10 ..=99 => {
221+ let r = LUT [ top. num as usize ] ;
222+ top. num = r & ( 2u64 . pow ( 32 ) - 1 ) ;
223+ top. stones += insert_stone ( ( r >> 32 ) & ( 2u64 . pow ( 32 ) - 1 ) ) ;
224+ }
225+ 100 ..=999 => top. num *= 2024 ,
226+ 1000 ..=9999 => {
227+ top. stones += insert_stone ( top. num % 100 ) ;
228+ top. num = top. num / 100 ;
229+ }
230+ 10000 ..=99999 => top. num *= 2024 ,
231+ 100000 ..=999999 => {
232+ top. stones += insert_stone ( top. num % 1000 ) ;
233+ top. num = top. num / 1000 ;
234+ }
235+ 1000000 ..=9999999 => top. num *= 2024 ,
236+ 10000000 ..=99999999 => {
237+ top. stones += insert_stone ( top. num % 10000 ) ;
238+ top. num = top. num / 10000 ;
239+ }
240+ 100000000 ..=999999999 => top. num *= 2024 ,
241+ 1000000000 ..=9999999999 => {
242+ top. stones += insert_stone ( top. num % 100000 ) ;
243+ top. num = top. num / 100000 ;
244+ }
245+ 10000000000 ..=99999999999 => top. num *= 2024 ,
246+ 100000000000 ..=999999999999 => {
247+ top. stones += insert_stone ( top. num % 1000000 ) ;
248+ top. num = top. num / 1000000 ;
249+ }
250+ 1000000000000 ..=9999999999999 => top. num *= 2024 ,
251+ 10000000000000 ..=99999999999999 => {
252+ top. stones += insert_stone ( top. num % 10000000 ) ;
253+ top. num = top. num / 10000000 ;
254+ }
255+ 100000000000000 ..=999999999999999 => top. num *= 2024 ,
256+ 1000000000000000 ..=9999999999999999 => {
257+ top. stones += insert_stone ( top. num % 100000000 ) ;
258+ top. num = top. num / 100000000 ;
259+ }
260+ 10000000000000000 ..=99999999999999999 => top. num *= 2024 ,
261+ 100000000000000000 ..=999999999999999999 => {
262+ top. stones += insert_stone ( top. num % 1000000000 ) ;
263+ top. num = top. num / 1000000000 ;
264+ }
265+ 1000000000000000000 ..=9999999999999999999 => top. num *= 2024 ,
266+ 10000000000000000000 ..=u64:: MAX => {
267+ top. stones += insert_stone ( top. num % 10000000000 ) ;
268+ top. num = top. num / 10000000000 ;
269+ }
270+ }
205271 top. blinks_left -= 1 ;
206272 }
207273 }
0 commit comments