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() {
|
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
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue