diff --git a/src/bin/05.rs b/src/bin/05.rs index 88e80a9..18df633 100644 --- a/src/bin/05.rs +++ b/src/bin/05.rs @@ -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 RangeExt for Range +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 { + start..(start + range) +} #[derive(Debug)] struct Mapping { - destination: u64, - source: u64, - range: u64, + destination: Range, + source: Range, } struct ParseMappingError; @@ -22,34 +37,26 @@ impl FromStr for Mapping { let nums: Vec = 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; 3] { + fn split_range(&self, r: Range) -> [Option>; 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]] } }