diff --git a/inputs/day02/example.txt b/inputs/day02/example.txt new file mode 100644 index 0000000..82cd679 --- /dev/null +++ b/inputs/day02/example.txt @@ -0,0 +1,6 @@ +7 6 4 2 1 +1 2 7 8 9 +9 7 6 2 1 +1 3 2 4 5 +8 6 4 4 1 +1 3 6 7 9 \ No newline at end of file diff --git a/src/day01.rs b/src/day01.rs index 9b30a03..0e8e0c5 100644 --- a/src/day01.rs +++ b/src/day01.rs @@ -1,32 +1,31 @@ -pub fn pt1(input: &str) -> i32 { +pub fn pt1(input: &str) -> usize { let elems = input .lines() .filter_map(|l| l.split_once(" ")) - .map(|(l, r)| (l.parse::(), r.parse::())) + .map(|(l, r)| (l.parse::(), r.parse::())) .filter(|(l, r)| l.is_ok() && r.is_ok()) .map(|(l, r)| (l.unwrap(), r.unwrap())); let mut lefts = elems.clone().map(|(l, _)| l).collect::>(); let mut rights = elems.map(|(_, r)| r).collect::>(); lefts.sort_unstable(); rights.sort_unstable(); - let res: u32 = lefts + lefts .iter() .zip(rights.iter()) .map(|(l, r)| l.abs_diff(*r)) - .sum(); - res as i32 + .sum() } -pub fn pt2(input: &str) -> i32 { +pub fn pt2(input: &str) -> usize { let elems = input .lines() .filter_map(|l| l.split_once(" ")) - .map(|(l, r)| (l.parse::(), r.parse::())) + .map(|(l, r)| (l.parse::(), r.parse::())) .filter(|(l, r)| l.is_ok() && r.is_ok()) .map(|(l, r)| (l.unwrap(), r.unwrap())); let lefts = elems.clone().map(|(l, _)| l); let rights = elems.map(|(_, r)| r).collect::>(); lefts - .map(|l| rights.clone().iter().filter(|r| **r == l).count() as i32 * l) + .map(|l| rights.clone().iter().filter(|r| **r == l).count() * l) .sum() } diff --git a/src/day02.rs b/src/day02.rs new file mode 100644 index 0000000..fbf0b92 --- /dev/null +++ b/src/day02.rs @@ -0,0 +1,64 @@ +use std::cmp::Ordering; + +pub fn pt1(input: &str) -> usize { + input + .lines() + .map(|l| { + l.split_whitespace() + .map(|s| s.parse::().unwrap()) + .collect::>() + }) + .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::().unwrap()) + .collect::>() + }) + .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) + } +} diff --git a/src/main.rs b/src/main.rs index bda1585..2eb4a15 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,14 @@ use std::fs::read_to_string; -use crate::day01::{pt1, pt2}; - mod day01; +mod day02; fn main() { println!("day 01!"); let input = read_to_string("./inputs/day01/input.txt").expect("Missing input.txt for day01"); - println!("And the result is: {}", pt1(&input)); - println!("Part 2: {}", pt2(&input)); + println!("And the result is: {}", day01::pt1(&input)); + println!("Part 2: {}", day01::pt2(&input)); + println!("day 02!"); + let input = read_to_string("./inputs/day02/input.txt").expect("Missing input.txt for day02"); + println!("And the result is: {}", day02::pt1(&input)); + println!("Part 2: {}", day02::pt2(&input)); }