1
0
Fork 0
2022/src/bin/day04.rs
Matej Focko da7c05bd1b
day(04): refactor
Signed-off-by: Matej Focko <mfocko@redhat.com>
2022-12-04 14:37:18 +01:00

100 lines
2.4 KiB
Rust

use std::ops::RangeInclusive;
use std::str::FromStr;
use aoc_2022::*;
use color_eyre::eyre::{Report, Result};
use tracing::*;
use tracing_subscriber::EnvFilter;
struct Assignment(RangeInclusive<i32>, RangeInclusive<i32>);
impl FromStr for Assignment {
type Err = Report;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let split_s = s.split(',').collect::<Vec<_>>();
let (left, right) = (split_s[0], split_s[1]);
let (l_split, r_split) = (
left.split('-').collect::<Vec<_>>(),
right.split('-').collect::<Vec<_>>(),
);
let (l_min, l_max) = (l_split[0], l_split[1]);
let (r_min, r_max) = (r_split[0], r_split[1]);
let (ll, lu) = (l_min.parse::<i32>()?, l_max.parse::<i32>()?);
let (rl, ru) = (r_min.parse::<i32>()?, r_max.parse::<i32>()?);
// debug!("Parsed: {}..={}, {}..={}", ll, lu, rl, ru);
Ok(Assignment(ll..=lu, rl..=ru))
}
}
impl Assignment {
fn fully_overlap(&self) -> bool {
let Assignment(l, r) = self;
(l.start() <= r.start() && r.end() <= l.end())
|| (r.start() <= l.start() && l.end() <= r.end())
}
fn overlap(&self) -> bool {
let Assignment(l, r) = self;
(l.contains(r.start()) || l.contains(r.end()))
|| (r.contains(l.start()) || r.contains(l.end()))
}
}
type Input = Vec<Assignment>;
type Output = usize;
fn part_1(input: &Input) -> Output {
input.iter().filter(|a| a.fully_overlap()).count()
}
fn part_2(input: &Input) -> Output {
input.iter().filter(|a| a.overlap()).count()
}
fn parse_input(pathname: &str) -> Input {
file_to_structs(pathname)
}
fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.with_target(false)
.with_file(true)
.with_line_number(true)
.without_time()
.compact()
.init();
color_eyre::install()?;
let input = parse_input("inputs/day04.txt");
info!("Part 1: {}", part_1(&input));
info!("Part 2: {}", part_2(&input));
Ok(())
}
#[cfg(test)]
mod day_04 {
use super::*;
#[test]
fn test_part_1() {
let sample = parse_input("samples/day04.txt");
assert_eq!(part_1(&sample), 2);
}
#[test]
fn test_part_2() {
let sample = parse_input("samples/day04.txt");
assert_eq!(part_2(&sample), 4);
}
}