Add day 5 (rough version)

bram
Bram 2025-12-05 08:50:25 +01:00
parent 1a3a64fca5
commit 4b18aacb36
2 changed files with 1287 additions and 4 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,104 @@
// use crate::utils;
use crate::utils;
pub fn answer(_text: String) -> (u32, u32) {
( 0, 0 )
}
pub fn answer(text: String) -> (u128, u128) {
let (r, ingredients) = match text.trim().split_once("\n\n") {
Some(x) => x,
None => return ( 0, 0 ),
};
let mut ranges: Vec<Range> = r
.split_whitespace()
.map(|s| Range::from(s).unwrap())
.collect();
merge_ranges(&mut ranges);
( ingredients.split_whitespace()
.map(|s| utils::str_to_u128(s).unwrap())
.filter(|n| ranges.iter().any(|range| range.contains(*n)))
.count() as u128
, ranges.iter().map(|r| r.size()).sum()
)
}
struct Range {
low : u128,
high : u128,
}
impl Range {
fn contains(&self, x : u128) -> bool {
self.low <= x && x <= self.high
}
fn from(s : &str) -> Option<Range> {
let (n1, n2) = s.trim().split_once("-")?;
let low = utils::str_to_u128(n1)?;
let high = utils::str_to_u128(n2)?;
if low <= high {
Some(Range::new(low, high))
} else {
None
}
}
fn new(low : u128, high : u128) -> Range {
assert!(low <= high);
Range { low : low, high : high }
}
/* Checks if two ranges overlap. If so, returns a mixed range. */
fn overlaps_with(&self, other: &Range) -> Option<Range> {
let highest_low = self.low.max(other.low);
let lowest_high = self.high.min(other.high);
if highest_low <= lowest_high {
Some(Range::new(
self.low.min(other.low),
self.high.max(other.high)
))
} else {
None
}
}
fn size(&self) -> u128 {
self.high - self.low + 1
}
}
fn merge_ranges(ranges: &mut Vec<Range>) {
// let mut merged: Vec<Range> = Vec::new();
for i in 0..ranges.len() {
loop {
let mut to_merge : Option<( usize, usize, Range )> = None;
if let Some(r1) = ranges.get(i) {
for j in (i+1)..ranges.len() {
if let Some(r2) = ranges.get(j) {
match r1.overlaps_with(r2) {
Some(r3) => {
to_merge = Some(( i, j, r3 ));
break;
},
None => {},
}
}
}
} else {
break;
}
match to_merge {
Some(( i, j, x )) => {
ranges.remove(j);
ranges.remove(i);
ranges.push(x);
},
None => { break; },
}
}
}
}