@@ -2,26 +2,50 @@ use std::{hint::unreachable_unchecked, mem::MaybeUninit, num::NonZero};
22
33use aoc_runner_derive:: aoc;
44
5- fn search ( target : u64 , v : & [ NonZero < u64 > ] ) -> bool {
6- match v {
7- [ ] => unsafe { unreachable_unchecked ( ) } ,
8- [ rest @ .., last] => {
9- let last = last. get ( ) ;
10- if rest. is_empty ( ) {
11- return target == last;
12- }
13- if last > target {
14- return false ;
15- }
16-
17- if target % last == 0 {
18- if search ( target / last, rest) {
19- return true ;
5+ macro_rules! search_fn {
6+ ( $name: ident => $name_next: ident) => {
7+ #[ inline( always) ]
8+ unsafe fn $name( target: u64 , v: & [ NonZero <u64 >] ) -> bool {
9+ match v {
10+ [ ] => unsafe { unreachable_unchecked( ) } ,
11+ [ rest @ .., last] => {
12+ let last = last. get( ) ;
13+ if last > target {
14+ return false ;
15+ }
16+
17+ if target % last == 0 {
18+ if $name_next( target / last, rest) {
19+ return true ;
20+ }
21+ }
22+
23+ return $name_next( target - last, rest) ;
2024 }
2125 }
26+ }
27+ } ;
28+ }
2229
23- return search ( target - last, rest) ;
30+ search_fn ! ( search_12 => search_11) ;
31+ search_fn ! ( search_11 => search_10) ;
32+ search_fn ! ( search_10 => search_9) ;
33+ search_fn ! ( search_9 => search_8) ;
34+ search_fn ! ( search_8 => search_7) ;
35+ search_fn ! ( search_7 => search_6) ;
36+ search_fn ! ( search_6 => search_5) ;
37+ search_fn ! ( search_5 => search_4) ;
38+ search_fn ! ( search_4 => search_3) ;
39+ search_fn ! ( search_3 => search_2) ;
40+ search_fn ! ( search_2 => search_1) ;
41+
42+ #[ inline( always) ]
43+ unsafe fn search_1 ( target : u64 , v : & [ NonZero < u64 > ] ) -> bool {
44+ match v {
45+ [ last] => {
46+ return target == last. get ( ) ;
2447 }
48+ _ => unsafe { unreachable_unchecked ( ) } ,
2549 }
2650}
2751
@@ -67,7 +91,21 @@ unsafe fn part1_inner(s: &str) -> u64 {
6791
6892 let init = & * ( v. get_unchecked ( ..v_len) as * const [ MaybeUninit < NonZero < u64 > > ]
6993 as * const [ NonZero < u64 > ] ) ;
70- if search ( target, init) {
94+ if match init. len ( ) {
95+ 1 => search_1 ( target, init) ,
96+ 2 => search_2 ( target, init) ,
97+ 3 => search_3 ( target, init) ,
98+ 4 => search_4 ( target, init) ,
99+ 5 => search_5 ( target, init) ,
100+ 6 => search_6 ( target, init) ,
101+ 7 => search_7 ( target, init) ,
102+ 8 => search_8 ( target, init) ,
103+ 9 => search_9 ( target, init) ,
104+ 10 => search_10 ( target, init) ,
105+ 11 => search_11 ( target, init) ,
106+ 12 => search_12 ( target, init) ,
107+ _ => unreachable_unchecked ( ) ,
108+ } {
71109 sum += target;
72110 }
73111 v_len = 0 ;
0 commit comments