Add day 5 (rough version)
parent
1a3a64fca5
commit
4b18aacb36
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,104 @@
|
||||||
// use crate::utils;
|
use crate::utils;
|
||||||
|
|
||||||
pub fn answer(_text: String) -> (u32, u32) {
|
pub fn answer(text: String) -> (u128, u128) {
|
||||||
( 0, 0 )
|
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; },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue