day(04): add initial solution
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
2920960efa
commit
3a30260c85
2 changed files with 105 additions and 0 deletions
6
samples/day04.txt
Normal file
6
samples/day04.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
2-4,6-8
|
||||||
|
2-3,4-5
|
||||||
|
5-7,7-9
|
||||||
|
2-8,3-7
|
||||||
|
6-6,4-6
|
||||||
|
2-6,4-8
|
99
src/bin/day04.rs
Normal file
99
src/bin/day04.rs
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
use std::ops::{Range, RangeInclusive};
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::{collections::HashSet, ops::RangeBounds};
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Input = Vec<Assignment>;
|
||||||
|
type Output = i32;
|
||||||
|
|
||||||
|
fn part_1(input: &Input) -> Output {
|
||||||
|
input
|
||||||
|
.iter()
|
||||||
|
.filter(|Assignment(l, r)| {
|
||||||
|
(l.start() <= r.start() && r.end() <= l.end())
|
||||||
|
|| (r.start() <= l.start() && l.end() <= r.end())
|
||||||
|
})
|
||||||
|
.count() as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_2(input: &Input) -> Output {
|
||||||
|
input
|
||||||
|
.iter()
|
||||||
|
.filter(|Assignment(l, r)| {
|
||||||
|
l.contains(r.start())
|
||||||
|
|| l.contains(r.end())
|
||||||
|
|| r.contains(l.start())
|
||||||
|
|| r.contains(l.end())
|
||||||
|
})
|
||||||
|
.count() as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue