This commit is contained in:
2025-12-07 05:27:13 +01:00
parent 6bef9799b9
commit 26942c7f31
2 changed files with 145 additions and 1 deletions

143
src/day5.rs Normal file
View 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)
}
}

View File

@@ -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 }