Skip to content

Commit bf18292

Browse files
committed
Unroll recursion
1 parent 8999f74 commit bf18292

File tree

1 file changed

+55
-17
lines changed

1 file changed

+55
-17
lines changed

src/day7.rs

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,50 @@ use std::{hint::unreachable_unchecked, mem::MaybeUninit, num::NonZero};
22

33
use 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

Comments
 (0)