wip: solve with range type

This commit is contained in:
Matej Janezic 2023-12-06 18:58:58 +01:00
parent 00000140d3
commit 0000015049
Signed by: janezicmatej
GPG Key ID: 4298E230ED37B2C0
1 changed files with 31 additions and 24 deletions

View File

@ -1,17 +1,32 @@
use std::{
cmp::{max, min},
ops::Range,
str::FromStr,
};
use aoc::parsers::to_vec;
type PairRange = (u64, u64);
trait RangeExt {
fn overlaps(&self, other: &Self) -> bool;
}
impl<T> RangeExt for Range<T>
where
T: PartialOrd,
{
fn overlaps(&self, other: &Self) -> bool {
self.contains(&other.start) || self.contains(&other.end)
}
}
fn build_range(start: u64, range: u64) -> Range<u64> {
start..(start + range)
}
#[derive(Debug)]
struct Mapping {
destination: u64,
source: u64,
range: u64,
destination: Range<u64>,
source: Range<u64>,
}
struct ParseMappingError;
@ -22,34 +37,26 @@ impl FromStr for Mapping {
let nums: Vec<u64> = to_vec(s, ' ');
Ok(Self {
destination: nums[0],
source: nums[1],
range: nums[2],
destination: build_range(nums[2], nums[0]),
source: build_range(nums[1], nums[0]),
})
}
}
impl Mapping {
fn contains(&self, n: u64) -> bool {
n >= self.source && n < self.source + self.range
}
fn contains_any(&self, (s, r): PairRange) -> bool {
s < self.source + self.range && s + r > self.source
}
fn map(&self, n: u64) -> u64 {
let shift = n - self.source;
self.destination + shift
let shift = n - self.source.start;
self.destination.start + shift
}
fn split_range(&self, (s, r): PairRange) -> [Option<PairRange>; 3] {
fn split_range(&self, r: Range<u64>) -> [Option<Range<u64>>; 3] {
let mut fences = [
s,
s + r,
max(self.source, s),
min(self.source + self.range, s + r),
r.start,
r.end,
max(self.source.start, r.start),
min(self.source.end, r.end),
];
fences.sort();
let mut v = Vec::new();
@ -58,13 +65,13 @@ impl Mapping {
let f = fences[i];
let nf = fences[i + 1];
if f != nf {
v.push(Some((f, nf - f)))
v.push(Some(f..(nf - f)))
} else {
v.push(None)
}
}
v[..3].try_into().unwrap()
[v[0], v[1], v[2]]
}
}