From b3bf7b2a97b5c8c8294568e4e8f9ffd01b374b3c Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 9 Dec 2023 14:11:16 +0100 Subject: [PATCH] optimize --- 2023/day09/src/less_alloc.rs | 48 ++++++++++++++++++++++++++++++++++++ 2023/day09/src/lib.rs | 4 +++ 2 files changed, 52 insertions(+) create mode 100644 2023/day09/src/less_alloc.rs diff --git a/2023/day09/src/less_alloc.rs b/2023/day09/src/less_alloc.rs new file mode 100644 index 0000000..68a5714 --- /dev/null +++ b/2023/day09/src/less_alloc.rs @@ -0,0 +1,48 @@ +use std::ops::Add; + +fn parse(input: &str) -> impl Iterator + '_> + '_ { + input + .lines() + .map(|line| line.split_ascii_whitespace().map(|s| s.parse().unwrap())) +} +fn execute( + input: impl Iterator>, + last_or_first: impl Fn(&[i64]) -> i64, + fold: impl Fn(i64, i64) -> i64 + Copy, +) -> i64 { + let mut values = Vec::with_capacity(128); + let mut derive = Vec::with_capacity(128); + + let mut last_values = Vec::with_capacity(16); + + input + .map(|values_iter| { + values.clear(); + + values.extend(values_iter); + derive.clone_from(&values); + + last_values.clear(); + last_values.push(last_or_first(&values)); + + while !derive.iter().all(|&n| n == 0) { + values.clear(); + values.extend(derive.windows(2).map(|s| s[1] - s[0])); + + last_values.push(last_or_first(&values)); + + std::mem::swap(&mut values, &mut derive); + } + + last_values.iter().copied().rev().fold(0, fold) + }) + .sum::() +} + +pub fn part1(input: &str) -> u64 { + execute(parse(input), |s| *s.last().unwrap(), Add::add) as u64 +} + +pub fn part2(input: &str) -> u64 { + execute(parse(input), |s| *s.first().unwrap(), |a, b| b - a) as u64 +} diff --git a/2023/day09/src/lib.rs b/2023/day09/src/lib.rs index 7314d6b..47905f3 100644 --- a/2023/day09/src/lib.rs +++ b/2023/day09/src/lib.rs @@ -1,3 +1,5 @@ +mod less_alloc; + use std::ops::Add; use helper::{Day, Variants}; @@ -12,9 +14,11 @@ helper::define_variants! { day => crate::Day09; part1 { basic => crate::part1; + less_alloc => crate::less_alloc::part1; } part2 { basic => crate::part2; + less_alloc => crate::less_alloc::part2; } }