Solve day04
This commit is contained in:
parent
7982e1c56f
commit
7e12364a29
1000
day04/input
Normal file
1000
day04/input
Normal file
File diff suppressed because it is too large
Load diff
6
day04/input.test
Normal file
6
day04/input.test
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
|
|
@ -1,3 +1,106 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
use std::{
|
||||
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
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue