aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/day1.rs71
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
+}