day 5
This commit is contained in:
143
src/day5.rs
Normal file
143
src/day5.rs
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
use std::cmp;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
struct UintInclusiveRange {
|
||||||
|
start: u64,
|
||||||
|
end: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UintInclusiveRange {
|
||||||
|
fn new(start: u64, end: u64) -> Self {
|
||||||
|
UintInclusiveRange {
|
||||||
|
start: start,
|
||||||
|
end: end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn in_range(&self, value: u64) -> bool {
|
||||||
|
value >= self.start && value <= self.end
|
||||||
|
}
|
||||||
|
|
||||||
|
fn overlaps(&self, other: &UintInclusiveRange) -> bool {
|
||||||
|
(self.start >= other.start && self.start <= other.end)
|
||||||
|
|| (self.end >= other.start && self.end <= other.end)
|
||||||
|
|| (self.start <= other.start && self.end >= other.end)
|
||||||
|
|| (self.start >= other.start && self.end <= other.end)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join(&self, other: &UintInclusiveRange) -> UintInclusiveRange {
|
||||||
|
println!(
|
||||||
|
"Joining {:?} and {:?} into {:?}",
|
||||||
|
self,
|
||||||
|
other,
|
||||||
|
UintInclusiveRange::new(
|
||||||
|
cmp::min(self.start, other.start),
|
||||||
|
cmp::max(self.end, other.end),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert!(self.overlaps(&other));
|
||||||
|
UintInclusiveRange::new(
|
||||||
|
cmp::min(self.start, other.start),
|
||||||
|
cmp::max(self.end, other.end),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size(self) -> u64 {
|
||||||
|
self.end - self.start + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(input: &str) -> (Vec<UintInclusiveRange>, Vec<u64>) {
|
||||||
|
(
|
||||||
|
input
|
||||||
|
.split("\n")
|
||||||
|
.take_while(|x| *x != "")
|
||||||
|
.map(|x| {
|
||||||
|
UintInclusiveRange::new(
|
||||||
|
x.split("-").nth(0).unwrap().parse().unwrap(),
|
||||||
|
x.split("-").nth(1).unwrap().parse().unwrap(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<UintInclusiveRange>>(),
|
||||||
|
input
|
||||||
|
.split("\n")
|
||||||
|
.skip_while(|x| *x != "")
|
||||||
|
.filter(|&x| !x.is_empty())
|
||||||
|
.map(|x| x.parse::<u64>().unwrap())
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day5, part1)]
|
||||||
|
pub fn part1(input: &str) -> u64 {
|
||||||
|
let (fresh_ingredients, available_ingredients) = parse_input(input);
|
||||||
|
available_ingredients
|
||||||
|
.iter()
|
||||||
|
.filter(|x| fresh_ingredients.iter().any(|y| y.in_range(**x)))
|
||||||
|
.count() as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day5, part2)]
|
||||||
|
pub fn part2(input: &str) -> u64 {
|
||||||
|
let (mut fresh_ingredients, _) = parse_input(input);
|
||||||
|
|
||||||
|
let mut joined_ingredients = <Vec<UintInclusiveRange>>::new();
|
||||||
|
|
||||||
|
fresh_ingredients.sort_by(|x, y| x.start.cmp(&y.start));
|
||||||
|
let mut init = UintInclusiveRange::new(0, 0);
|
||||||
|
|
||||||
|
for ingredient in &fresh_ingredients {
|
||||||
|
if ingredient.start <= init.end {
|
||||||
|
init = UintInclusiveRange::new(init.start, init.end.max(ingredient.end));
|
||||||
|
} else {
|
||||||
|
if init.start != 0 && init.end != 0 {
|
||||||
|
joined_ingredients.push(init);
|
||||||
|
}
|
||||||
|
init = UintInclusiveRange::new(ingredient.start, ingredient.end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
joined_ingredients.push(init);
|
||||||
|
|
||||||
|
joined_ingredients.iter().map(|x| x.size()).sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part1() {
|
||||||
|
let test_input = String::from(
|
||||||
|
"3-5
|
||||||
|
10-14
|
||||||
|
16-20
|
||||||
|
12-18
|
||||||
|
|
||||||
|
1
|
||||||
|
5
|
||||||
|
8
|
||||||
|
11
|
||||||
|
17
|
||||||
|
32",
|
||||||
|
);
|
||||||
|
assert_eq!(part1(&test_input), 3)
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_part2() {
|
||||||
|
let test_input = String::from(
|
||||||
|
"3-5
|
||||||
|
10-14
|
||||||
|
16-20
|
||||||
|
12-18
|
||||||
|
|
||||||
|
1
|
||||||
|
5
|
||||||
|
8
|
||||||
|
11
|
||||||
|
17
|
||||||
|
32",
|
||||||
|
);
|
||||||
|
assert_eq!(part2(&test_input), 14)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ extern crate aoc_runner_derive;
|
|||||||
// pub mod day1;
|
// pub mod day1;
|
||||||
// pub mod day2;
|
// pub mod day2;
|
||||||
// pub mod day3;
|
// pub mod day3;
|
||||||
pub mod day4;
|
// pub mod day4;
|
||||||
|
pub mod day5;
|
||||||
|
|
||||||
aoc_lib! { year = 2025 }
|
aoc_lib! { year = 2025 }
|
||||||
|
|||||||
Reference in New Issue
Block a user