aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/day1.rs106
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
+ }
+ )
+}