diff options
Diffstat (limited to 'src/day1.rs')
-rw-r--r-- | src/day1.rs | 106 |
1 files changed, 85 insertions, 21 deletions
diff --git a/src/day1.rs b/src/day1.rs index 1685dbd..3e9037a 100644 --- a/src/day1.rs +++ b/src/day1.rs @@ -59,7 +59,7 @@ pub fn solve_part2_iterators(input : &Vec<u32>) -> usize { sliding_window.zip(old_window).filter(|(new, old)| new > old).count() } -enum FloatingWindow { +enum FloatingWindowFallible { Prewarming{ value : u32, previous : [u32;2], @@ -72,59 +72,123 @@ enum FloatingWindow { }, } -impl FloatingWindow { +impl FloatingWindowFallible { fn try_get(&self) -> Option<u32> { match self { - FloatingWindow::Prewarming{..} => { None } - FloatingWindow::Ready{value, ..} => { Some(*value) } + FloatingWindowFallible::Prewarming{..} => { None } + FloatingWindowFallible::Ready{value, ..} => { Some(*value) } } } } -impl Default for FloatingWindow { +impl Default for FloatingWindowFallible { fn default() -> Self { - FloatingWindow::Prewarming{value:0,previous:[0;2],index:0} + FloatingWindowFallible::Prewarming{value:0,previous:[0;2],index:0} } } -impl Add<u32> for FloatingWindow { - type Output = FloatingWindow; - fn add(self, rhs : u32) -> FloatingWindow { +impl Add<u32> for FloatingWindowFallible { + type Output = FloatingWindowFallible; + fn add(self, rhs : u32) -> FloatingWindowFallible { match self { - FloatingWindow::Prewarming{value, previous, index} if index < 2 => { + FloatingWindowFallible::Prewarming{value, previous, index} if index < 2 => { let mut arr = previous; arr[index] = rhs; - FloatingWindow::Prewarming{value: value + rhs, previous : arr, index: index + 1} + FloatingWindowFallible::Prewarming{value: value + rhs, previous : arr, index: index + 1} } - FloatingWindow::Prewarming{value, previous, index} => { + FloatingWindowFallible::Prewarming{value, previous, ..} => { let arr = [previous[0], previous[1], rhs]; - FloatingWindow::Ready{value: value + rhs, previous : arr, index: 0} + FloatingWindowFallible::Ready{value: value + rhs, previous : arr, index: 0} } - FloatingWindow::Ready{value, previous, index} => { + FloatingWindowFallible::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} + FloatingWindowFallible::Ready{value: (value + rhs) - old, previous : arr, index: (index + 1)%3} } } } } -#[aoc(day1, part2, AccumulatorType)] +#[aoc(day1, part2, AccumulatorTypeFallible)] pub fn solve_part2_accumulator_type(input : &Vec<u32>) -> u32 { struct Helper { - floating_window : FloatingWindow, + floating_window : FloatingWindowFallible, prev : Option<u32>, count : u32, } input.iter() .fold( - Helper{floating_window : FloatingWindow::default(), prev : None, count: 0}, + Helper{floating_window : FloatingWindowFallible::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} + let count = count + prev.zip(curr).map(|(prev,curr)| if curr > prev {1} else {0}).unwrap_or(0); + Helper{floating_window, prev: curr, count} } ).count } + +struct FloatingWindow { + value : u32, + previous : [u32;3], + index : usize, +} + +impl Add<u32> for FloatingWindow { + type Output = FloatingWindow; + fn add(self, rhs : u32) -> FloatingWindow { + let mut arr = self.previous; + let old = arr[self.index]; + arr[self.index] = rhs; + FloatingWindow{value : (self.value + rhs) - old, previous : arr, index: (self.index + 1)%3} + } +} + +struct FloatingWindowInitializer { + value : u32, + previous : [u32;2], + index : usize, +} + +type FloatingWindowInitializerStep = std::ops::ControlFlow<FloatingWindow,FloatingWindowInitializer>; + +impl FloatingWindowInitializer { + fn add_step(self, input : &u32) -> FloatingWindowInitializerStep { + if self.index == 2 { + FloatingWindowInitializerStep::Break(FloatingWindow{ value : self.value + input, previous : [self.previous[0], self.previous[1], *input], index : 0}) + } + else { + let mut arr = self.previous; + arr[self.index] = *input; + FloatingWindowInitializerStep::Continue(FloatingWindowInitializer{ value: self.value + input, previous : arr, index : self.index + 1}) + } + } +} + +impl Default for FloatingWindowInitializer { + fn default() -> Self { + Self{value : 0, previous : [0;2], index : 0} + } +} + +#[aoc(day1, part2, AccumulatorTypeInfallible)] +pub fn solve_part2_accumulator_infallible(input : &Vec<u32>) -> Option<u32> { + let floating_window = match input.iter() + .try_fold( + FloatingWindowInitializer::default(), + FloatingWindowInitializer::add_step) { + FloatingWindowInitializerStep::Break(fw) => {Some(fw)} + FloatingWindowInitializerStep::Continue(_) => {None} + }; + floating_window.map(|f| { + input.iter().skip(3).fold((f,0),|(f,c), u| { + let old = f.value; + let f = f+*u; + if f.value > old { + (f,c+1) + } else { + (f,c) + }}).1 + } + ) +} |