diff options
author | Santo Cariotti <santo@dcariotti.me> | 2023-04-27 11:06:30 +0200 |
---|---|---|
committer | Santo Cariotti <santo@dcariotti.me> | 2023-04-27 11:06:30 +0200 |
commit | 234aed363e1e181f458611505afaf06a54e377d3 (patch) | |
tree | 3ae36d1bbc47caae0e1795c8041cca7183674ea7 /2022/day4/src | |
parent | 6f0383f0b1dd202b11758da3448aec99dc3084fc (diff) |
Add day4
Diffstat (limited to '2022/day4/src')
-rw-r--r-- | 2022/day4/src/lib.rs | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/2022/day4/src/lib.rs b/2022/day4/src/lib.rs new file mode 100644 index 0000000..e64021b --- /dev/null +++ b/2022/day4/src/lib.rs @@ -0,0 +1,126 @@ +use std::cmp::{max, min}; +use std::convert::From; + +#[derive(Debug)] +struct Range { + start: i16, + end: i16, +} + +#[derive(Debug)] +struct Ranges { + one: Range, + two: Range, +} + +impl From<&str> for Range { + fn from(item: &str) -> Self { + let dash_idx = item.find("-").expect("Can't find dash, can't parse."); + let start: i16 = item[..dash_idx].parse().unwrap(); + let end: i16 = item[dash_idx + 1..].parse().unwrap(); + + Range { start, end } + } +} + +impl From<&str> for Ranges { + fn from(item: &str) -> Self { + let comma_idx = item.find(",").expect("Comma not found, can't parse."); + + Ranges { + one: item[..comma_idx].into(), + two: item[comma_idx + 1..].into(), + } + } +} + +impl Ranges { + fn are_subset(&self) -> bool { + let a = &self.one; + let b = &self.two; + + if a.start <= b.start && a.end >= b.end { + return true; + } + + if b.start <= a.start && b.end >= a.end { + return true; + } + + false + } + + fn are_overlap(&self) -> bool { + let a = &self.one; + let b = &self.two; + + return min(a.end, b.end) - max(a.start, b.start) >= 0; + } +} + +pub fn part1(input: &str) -> u32 { + let ranges: Vec<Ranges> = input.trim().lines().map(|x| x.into()).collect(); + let mut tot: u32 = 0; + + for range in ranges { + if range.are_subset() { + tot += 1; + } + } + + tot +} + +pub fn part2(input: &str) -> u32 { + let ranges: Vec<Ranges> = input.trim().lines().map(|x| x.into()).collect(); + let mut tot: u32 = 0; + + for range in ranges { + if range.are_subset() || range.are_overlap() { + tot += 1; + } + } + + tot +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_example() { + let data = include_str!("../example.txt"); + + let result = part1(data); + + assert_eq!(result, 2); + } + + #[test] + fn test_input1() { + let data = include_str!("../input.txt"); + + let result = part1(data); + + assert_eq!(result, 595); + } + + #[test] + fn test_example2() { + let data = include_str!("../example.txt"); + + let result = part2(data); + + assert_eq!(result, 4); + } + + #[test] + fn test_input2() { + let data = include_str!("../input.txt"); + + let result = part2(data); + + assert_eq!(result, 952); + } +} |