1
0
Fork 0
advent-of-code/src/bin/p04.rs

97 lines
2.5 KiB
Rust

#![feature(iterator_try_collect)]
use std::fs;
use std::io::{self, BufRead};
use std::ops::RangeInclusive;
use std::str::FromStr;
#[derive(Debug)]
struct WorkRange(RangeInclusive<u32>);
impl WorkRange {
#[allow(dead_code)]
fn init(start: u32, end: u32) -> Self {
WorkRange(start..=end)
}
fn fully_contains(&self, other: &Self) -> bool {
self.0.contains(other.0.start()) && self.0.contains(other.0.end())
}
fn overlaps(&self, other: &Self) -> 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())
}
}
impl FromStr for WorkRange {
type Err = <u32 as FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let spl: Vec<u32> = s.split('-').map(|n| n.parse()).try_collect()?;
Ok(WorkRange(spl[0]..=spl[1]))
}
}
#[derive(Debug)]
struct ElfPair(WorkRange, WorkRange);
impl FromStr for ElfPair {
type Err = <WorkRange as FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let spl: Vec<&str> = s.split(',').collect();
Ok(ElfPair(spl[0].parse()?, spl[1].parse()?))
}
}
fn main() {
let filename = "etc/p04.txt";
let file = fs::File::open(filename).expect("Can't open file");
let reader = io::BufReader::new(file);
println!("PART ONE ---------------");
let pairs: Vec<ElfPair> = reader
.lines()
.flat_map(|l| l.expect("Expect valid line").parse())
.collect();
part1(&pairs);
println!("\n PART TWO ---------------");
part2(&pairs);
}
fn part1(pairs: &[ElfPair]) {
let sum = pairs
.iter()
.filter(|ElfPair(l, r)| l.fully_contains(r) || r.fully_contains(l))
.count();
println!("num containing: {}", sum);
}
fn part2(pairs: &[ElfPair]) {
let sum = pairs
.iter()
.filter(|ElfPair(l, r)| l.overlaps(r) || r.overlaps(l))
.count();
println!("num overlapping: {}", sum);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn range_overlaps() {
assert!(!WorkRange::init(2, 4).overlaps(&WorkRange::init(6, 8)));
assert!(!WorkRange::init(2, 3).overlaps(&WorkRange::init(4, 5)));
assert!(WorkRange::init(5, 7).overlaps(&WorkRange::init(7, 9)));
assert!(WorkRange::init(2, 8).overlaps(&WorkRange::init(3, 7)));
assert!(WorkRange::init(6, 6).overlaps(&WorkRange::init(4, 6)));
assert!(WorkRange::init(2, 6).overlaps(&WorkRange::init(4, 8)));
}
}