summaryrefslogtreecommitdiff
path: root/2024/02/rust/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to '2024/02/rust/src/main.rs')
-rw-r--r--2024/02/rust/src/main.rs37
1 files changed, 12 insertions, 25 deletions
diff --git a/2024/02/rust/src/main.rs b/2024/02/rust/src/main.rs
index 620fe8b..2007837 100644
--- a/2024/02/rust/src/main.rs
+++ b/2024/02/rust/src/main.rs
@@ -1,3 +1,5 @@
+#![feature(iter_map_windows)]
+
use std::io;
fn main() {
@@ -12,35 +14,20 @@ fn main() {
.collect::<Result<Vec<_>, _>>()
.unwrap();
- let silver: usize = input.iter().map(self::safe).flatten().count();
- let gold: u64 = 0;
+ let silver: usize = input.iter().filter(|&xs| all_safe(xs)).count();
+ let gold: usize = input.iter().filter(|&xs| drop_safe(xs)).count();
println!("silver: {silver}");
println!("gold: {gold}");
}
-#[derive(Debug, PartialEq)]
-enum Dir {
- Asc,
- Desc,
+fn all_safe(xs: &Vec<i64>) -> bool {
+ let mut diffs = xs.iter().map_windows(|&[x, y]| y - x).peekable();
+ let dir = diffs.peek().unwrap_or(&1).signum();
+ diffs.all(|d| (1..=3).contains(&d.abs()) && d.signum() == dir)
}
-fn safe(xs: &Vec<i64>) -> Option<Dir> {
- let mut dirs = xs
- .iter()
- .zip(xs.iter().skip(1))
- .map(|(x, y)| y - x)
- .map(|d| match d {
- -3..=-1 => Some(Dir::Desc),
- 1..=3 => Some(Dir::Asc),
- _ => None,
- })
- .collect::<Option<Vec<Dir>>>()?
- .into_iter();
-
- let head = dirs.next().unwrap_or(Dir::Asc);
- if dirs.all(|d| d == head) {
- Some(head)
- } else {
- None
- }
+fn drop_safe(xs: &Vec<i64>) -> bool {
+ (0..xs.len())
+ .map(|idx| xs.split_at(idx))
+ .any(|(left, right)| all_safe(&[left, &right[1..]].concat()))
}