diff --git a/2023/day07/src/lib.rs b/2023/day07/src/lib.rs index e307f77..a21df89 100644 --- a/2023/day07/src/lib.rs +++ b/2023/day07/src/lib.rs @@ -14,14 +14,14 @@ struct Day07; helper::define_variants! { day => crate::Day07; part1 { - basic => crate::part1, sample_count=10000; - unstable_sort => crate::unstable_sort::part1, sample_count=10000; - sort_cache => crate::precompute_more::part1, sample_count=10000; + basic => crate::part1; + unstable_sort => crate::unstable_sort::part1; + sort_cache => crate::precompute_more::part1; } part2 { - basic => crate::part2, sample_count=10000; - unstable_sort => crate::unstable_sort::part2, sample_count=10000; - sort_cache => crate::precompute_more::part2, sample_count=10000; + basic => crate::part2; + unstable_sort => crate::unstable_sort::part2; + sort_cache => crate::precompute_more::part2; } } diff --git a/2023/day09/src/lib.rs b/2023/day09/src/lib.rs index 48cc7a2..562d1f1 100644 --- a/2023/day09/src/lib.rs +++ b/2023/day09/src/lib.rs @@ -1,5 +1,6 @@ mod less_alloc; mod number_parsing; +mod unify_parsing; use std::ops::Add; @@ -17,11 +18,13 @@ helper::define_variants! { basic => crate::part1; less_alloc => crate::less_alloc::part1; number_parsing => crate::number_parsing::part1; + unify_parsing => crate::unify_parsing::part1; } part2 { basic => crate::part2; less_alloc => crate::less_alloc::part2; number_parsing => crate::number_parsing::part2; + unify_parsing => crate::unify_parsing::part2; } } diff --git a/2023/day09/src/unify_parsing.rs b/2023/day09/src/unify_parsing.rs new file mode 100644 index 0000000..2bd722c --- /dev/null +++ b/2023/day09/src/unify_parsing.rs @@ -0,0 +1,75 @@ +use std::ops::Add; + +fn parse(input: &str, into: &mut Vec, mut line_callback: impl FnMut(&mut Vec)) { + let mut neg = false; + let mut acc = 0; + + for byte in input.bytes() { + match byte { + b' ' => { + if neg { + acc = -acc + }; + into.push(acc); + acc = 0; + neg = false; + } + b'-' => neg = true, + b'\n' => { + if neg { + acc = -acc + }; + into.push(acc); + line_callback(into); + into.clear(); + acc = 0; + neg = false; + } + // must be b'0'..=b'9' + _ => { + let value = byte - b'0'; + acc = (acc * 10) + (value as i64); + } + } + } +} + +fn execute( + input: &str, + last_or_first: impl Fn(&[i64]) -> i64, + fold: impl Fn(i64, i64) -> i64 + Copy, +) -> i64 { + let mut row1 = Vec::with_capacity(128); + let mut row2 = Vec::with_capacity(128); + + let mut last_values = Vec::with_capacity(16); + + let mut total = 0; + + parse(input, &mut row1, |row1| { + row2.clone_from(&row1); + + last_values.clear(); + last_values.push(last_or_first(&row1)); + while !row2.iter().all(|&n| n == 0) { + row1.clear(); + row1.extend(row2.windows(2).map(|s| s[1] - s[0])); + + last_values.push(last_or_first(&row1)); + + std::mem::swap(row1, &mut row2); + } + + total += last_values.iter().copied().rev().fold(0, fold); + }); + + total +} + +pub fn part1(input: &str) -> u64 { + execute(input, |s| *s.last().unwrap(), Add::add) as u64 +} + +pub fn part2(input: &str) -> u64 { + execute(input, |s| *s.first().unwrap(), |a, b| b - a) as u64 +} diff --git a/helper/src/lib.rs b/helper/src/lib.rs index 64b635c..bca0934 100644 --- a/helper/src/lib.rs +++ b/helper/src/lib.rs @@ -122,7 +122,7 @@ macro_rules! benchmarks { #[macro_export] macro_rules! _bench_sample_count { (;$($tt:tt)*) => { - #[::divan::bench(sample_count = 5000)] + #[::divan::bench(sample_count = 10000)] $($tt)* }; ($sample_count:expr; $($tt:tt)*) => {