diff options
author | Justin Wernick <justin@worthe-it.co.za> | 2022-12-04 19:44:11 +0200 |
---|---|---|
committer | Justin Wernick <justin@worthe-it.co.za> | 2022-12-04 19:44:11 +0200 |
commit | 8374ef5bc9d23c35b23ff1c9a9ba5f096b150921 (patch) | |
tree | 41ae2cc9d65f13bce1e8772d8ebff94c28333bc4 /2022/src | |
parent | 02973bde28a8a23d2657accda9b76bf9b6ebf61c (diff) |
Day 4
Diffstat (limited to '2022/src')
-rw-r--r-- | 2022/src/bin/day_4.rs | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/2022/src/bin/day_4.rs b/2022/src/bin/day_4.rs new file mode 100644 index 0000000..5f08d70 --- /dev/null +++ b/2022/src/bin/day_4.rs @@ -0,0 +1,88 @@ +use nom::{ + bytes::complete::tag, + character::complete::{line_ending, u32 as nom_u32}, + combinator::map, + multi::separated_list1, + sequence::tuple, + IResult, +}; +use std::{fs, iter::Iterator, ops::RangeInclusive}; + +fn main() -> Result<(), Box<dyn std::error::Error>> { + let input = fs::read_to_string("inputs/day_4.txt")?; + let assignments = Assignments::parser(&input).unwrap().1; + dbg!(assignments.count_containing_assignments()); + dbg!(assignments.count_overlapping_assignments()); + Ok(()) +} + +#[derive(Debug, PartialEq, Eq, Clone)] +struct Assignments(Vec<AssignmentPair>); + +#[derive(Debug, PartialEq, Eq, Clone)] +struct AssignmentPair { + elf_1: Assignment, + elf_2: Assignment, +} + +#[derive(Debug, PartialEq, Eq, Clone)] +struct Assignment(RangeInclusive<u32>); + +impl Assignments { + fn parser(input: &str) -> IResult<&str, Assignments> { + map( + separated_list1(line_ending, AssignmentPair::parser), + Assignments, + )(input) + } + + fn count_containing_assignments(&self) -> usize { + self.0 + .iter() + .filter(|pair| pair.one_completely_overlaps_other()) + .count() + } + + fn count_overlapping_assignments(&self) -> usize { + self.0 + .iter() + .filter(|pair| pair.one_overlaps_other()) + .count() + } +} + +impl AssignmentPair { + fn parser(input: &str) -> IResult<&str, AssignmentPair> { + map( + tuple((Assignment::parser, tag(","), Assignment::parser)), + |(elf_1, _, elf_2)| AssignmentPair { elf_1, elf_2 }, + )(input) + } + + fn one_completely_overlaps_other(&self) -> bool { + self.elf_1.contains(&self.elf_2) || self.elf_2.contains(&self.elf_1) + } + + fn one_overlaps_other(&self) -> bool { + self.elf_1.overlaps(&self.elf_2) + } +} + +impl Assignment { + fn parser(input: &str) -> IResult<&str, Assignment> { + map(tuple((nom_u32, tag("-"), nom_u32)), |(start, _, end)| { + Assignment(RangeInclusive::new(start, end)) + })(input) + } + + fn contains(&self, other: &Assignment) -> bool { + self.0.contains(other.0.start()) && self.0.contains(other.0.end()) + } + + fn overlaps(&self, other: &Assignment) -> bool { + self.0.contains(other.0.start()) + || self.0.contains(other.0.end()) + || other.0.contains(self.0.start()) + || other.0.contains(self.0.end()) + } +} |