65 lines
1.7 KiB
Rust
65 lines
1.7 KiB
Rust
use std::cmp::Ordering;
|
|
|
|
pub fn pt1(input: &str) -> usize {
|
|
input
|
|
.lines()
|
|
.map(|l| {
|
|
l.split_whitespace()
|
|
.map(|s| s.parse::<i32>().unwrap())
|
|
.collect::<Vec<_>>()
|
|
})
|
|
.filter(|v| is_safe(v))
|
|
.count()
|
|
}
|
|
pub fn is_safe(it: &[i32]) -> bool {
|
|
assert!((it.len() >= 2), "Not enough elements");
|
|
let first = it.first().unwrap();
|
|
let second = it[1];
|
|
match first.cmp(&second) {
|
|
Ordering::Less => it.windows(2).map(|w| w[1] - w[0]).all(|e| e > 0 && e <= 3),
|
|
Ordering::Equal => false,
|
|
Ordering::Greater => it.windows(2).map(|w| w[0] - w[1]).all(|e| e > 0 && e <= 3),
|
|
}
|
|
}
|
|
|
|
pub fn is_safe_skipping_one(it: &[i32]) -> bool {
|
|
is_safe(it)
|
|
|| (0..it.len()).any(|index_to_skip| {
|
|
let mut to_test = it.to_owned();
|
|
to_test.remove(index_to_skip);
|
|
is_safe(&to_test)
|
|
})
|
|
}
|
|
pub fn pt2(input: &str) -> usize {
|
|
input
|
|
.lines()
|
|
.map(|l| {
|
|
l.split_whitespace()
|
|
.map(|s| s.parse::<i32>().unwrap())
|
|
.collect::<Vec<_>>()
|
|
})
|
|
.filter(|v| is_safe_skipping_one(v))
|
|
.count()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use std::fs::read_to_string;
|
|
|
|
use crate::day02::{pt1, pt2};
|
|
|
|
#[test]
|
|
pub fn test_pt1() {
|
|
let input =
|
|
read_to_string("./inputs/day02/example.txt").expect("Missing example.txt for day02");
|
|
assert_eq!(pt1(&input), 2)
|
|
}
|
|
#[test]
|
|
pub fn test_pt2() {
|
|
let input =
|
|
read_to_string("./inputs/day02/example.txt").expect("Missing example.txt for day02");
|
|
|
|
assert_eq!(pt2(&input), 4)
|
|
}
|
|
}
|