diff options
-rw-r--r-- | src/day1.rs | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/day1.rs b/src/day1.rs index 1326af6..1685dbd 100644 --- a/src/day1.rs +++ b/src/day1.rs @@ -1,5 +1,6 @@ use aoc_runner_derive::*; use std::str::FromStr; +use std::ops::Add; #[aoc_generator(day1)] pub fn input_generator<'c>(input : &'c str) -> Vec<u32>{ @@ -57,3 +58,73 @@ pub fn solve_part2_iterators(input : &Vec<u32>) -> usize { let sliding_window = sliding_window.skip(1); sliding_window.zip(old_window).filter(|(new, old)| new > old).count() } + +enum FloatingWindow { + Prewarming{ + value : u32, + previous : [u32;2], + index : usize, + }, + Ready{ + value : u32, + previous : [u32;3], + index : usize, + }, +} + +impl FloatingWindow { + fn try_get(&self) -> Option<u32> { + match self { + FloatingWindow::Prewarming{..} => { None } + FloatingWindow::Ready{value, ..} => { Some(*value) } + } + } +} + +impl Default for FloatingWindow { + fn default() -> Self { + FloatingWindow::Prewarming{value:0,previous:[0;2],index:0} + } +} + +impl Add<u32> for FloatingWindow { + type Output = FloatingWindow; + fn add(self, rhs : u32) -> FloatingWindow { + match self { + FloatingWindow::Prewarming{value, previous, index} if index < 2 => { + let mut arr = previous; + arr[index] = rhs; + FloatingWindow::Prewarming{value: value + rhs, previous : arr, index: index + 1} + } + FloatingWindow::Prewarming{value, previous, index} => { + let arr = [previous[0], previous[1], rhs]; + FloatingWindow::Ready{value: value + rhs, previous : arr, index: 0} + } + FloatingWindow::Ready{value, previous, index} => { + let mut arr = previous; + let old = arr[index]; + arr[index] = rhs; + FloatingWindow::Ready{value: (value + rhs - old), previous : arr, index: (index + 1)%3} + } + } + } +} +#[aoc(day1, part2, AccumulatorType)] +pub fn solve_part2_accumulator_type(input : &Vec<u32>) -> u32 { + struct Helper { + floating_window : FloatingWindow, + prev : Option<u32>, + count : u32, + } + input.iter() + .fold( + Helper{floating_window : FloatingWindow::default(), prev : None, count: 0}, + |Helper{floating_window, prev, count}, i| { + let prev = floating_window.try_get(); + let floating_window = floating_window + *i; + let curr = floating_window.try_get(); + let count = count + prev.zip(curr).and_then(|(prev,curr)| (curr > prev).then(|| 1)).unwrap_or(0); + Helper{floating_window, prev, count} + } + ).count +} |