Solve day04

This commit is contained in:
Malte Tammena 2022-12-04 08:19:03 +01:00
parent 7982e1c56f
commit 7e12364a29
3 changed files with 1111 additions and 2 deletions

1000
day04/input Normal file

File diff suppressed because it is too large Load diff

6
day04/input.test Normal file
View 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

View file

@ -1,3 +1,106 @@
fn main() { use std::{
println!("Hello, world!"); fs::File,
io::{BufRead, BufReader},
ops::RangeInclusive,
};
/// Possible cases for two ranges
enum Sharing {
None,
Shared,
Contained,
}
/// Counting for the solution!
#[derive(Debug, Default, PartialEq, Eq)]
struct Counter {
shared: usize,
contained: usize,
}
/// Split a line with two ranges: `23-87,45-101`
fn parse_line<S: AsRef<str>>(line: S) -> [RangeInclusive<usize>; 2] {
let (first, second) = line
.as_ref()
.split_once(",")
.expect("A comma in every line");
let (first_from, first_to) = first.split_once("-").expect("A range with a dash");
let (second_from, second_to) = second.split_once("-").expect("A range with a dash");
[
first_from.parse().unwrap()..=first_to.parse().unwrap(),
second_from.parse().unwrap()..=second_to.parse().unwrap(),
]
}
/// Solve the puzzle:
/// How pairs of elves exist, where one's work is contained in the other?
/// How pairs of elves exist, where both are sharing parts of the work?
fn count<B: BufRead>(reader: B) -> Counter {
reader
.lines()
.map(Result::unwrap)
.map(parse_line)
.map(Sharing::from)
.collect()
}
fn main() {
let mut args = ::std::env::args().skip(1);
let file = args.next().unwrap_or_else(|| String::from("./input"));
let file = BufReader::new(File::open(file).expect("Input file not found"));
let counter = count(file);
println!("Contained: {}", counter.contained);
println!("Shared: {}", counter.shared);
}
impl From<[RangeInclusive<usize>; 2]> for Sharing {
fn from([first, second]: [RangeInclusive<usize>; 2]) -> Self {
let a = first.contains(second.start());
let b = first.contains(second.end());
let c = second.contains(first.start());
let d = second.contains(first.end());
if (a && b) || (c && d) {
Self::Contained
} else if a || b || c || d {
Self::Shared
} else {
Self::None
}
}
}
impl FromIterator<Sharing> for Counter {
fn from_iter<T: IntoIterator<Item = Sharing>>(iter: T) -> Self {
iter.into_iter().fold(Self::default(), |mut counter, el| {
match el {
Sharing::None => {}
Sharing::Shared => counter.shared += 1,
Sharing::Contained => {
counter.shared += 1;
counter.contained += 1;
}
}
counter
})
}
}
#[cfg(test)]
mod tests {
use std::io::Cursor;
use super::*;
#[test]
fn test_case_first_puzzle() {
let file = Cursor::new(include_str!("../input.test"));
let count = count(file);
assert_eq!(
count,
Counter {
contained: 2,
shared: 4
}
);
}
} }