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) {
|
||||
( 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; },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue