Advent of Code solutions in Rust

feat: add `try_union` function to `RangeSet` trait

+44
+44
aoc_utils/src/range.rs
··· 2 2 3 3 /// Extension trait for set operations on range types 4 4 pub trait RangeSet: Sized { 5 + fn try_union(&self, other: &Self) -> Option<Self>; 5 6 fn intersection(&self, other: &Self) -> Option<Self>; 6 7 } 7 8 ··· 9 10 where 10 11 T: Copy + PartialOrd + Ord, 11 12 { 13 + fn try_union(&self, other: &Self) -> Option<Self> { 14 + if self.contains(other.start()) { 15 + Some(*self.start()..=*self.end().max(other.end())) 16 + } else if other.contains(self.start()) { 17 + Some(*other.start()..=*self.end().max(other.end())) 18 + } else { 19 + None 20 + } 21 + } 22 + 12 23 fn intersection(&self, other: &Self) -> Option<Self> { 13 24 let range = (*self.start().max(other.start()))..=(*self.end().min(other.end())); 14 25 (!range.is_empty()).then_some(range) ··· 18 29 #[cfg(test)] 19 30 mod tests { 20 31 use super::*; 32 + 33 + #[test] 34 + fn inclusive_range_try_union() { 35 + // 1 2 3 4 5 6 7 8 36 + // --------- 37 + // ----------- 38 + assert_eq!(RangeSet::try_union(&(1..=5), &(3..=8)), Some(1..=8)); 39 + 40 + // 1 2 3 4 5 6 7 8 41 + // ----------- 42 + // --------- 43 + assert_eq!(RangeSet::try_union(&(3..=8), &(1..=5)), Some(1..=8)); 44 + 45 + // 1 2 3 4 5 6 7 8 46 + // --------------- 47 + // ----- 48 + assert_eq!(RangeSet::try_union(&(1..=8), &(3..=5)), Some(1..=8)); 49 + 50 + // 1 2 3 4 5 6 7 8 51 + // ----- 52 + // --------------- 53 + assert_eq!(RangeSet::try_union(&(3..=5), &(1..=8)), Some(1..=8)); 54 + 55 + // 1 2 3 4 5 6 7 8 56 + // ----- 57 + // ------- 58 + assert_eq!(RangeSet::try_union(&(1..=3), &(5..=8)), None); 59 + 60 + // 1 2 3 4 5 6 7 8 61 + // ------- 62 + // ----- 63 + assert_eq!(RangeSet::try_union(&(5..=8), &(1..=3)), None); 64 + } 21 65 22 66 #[test] 23 67 fn inclusive_range_intersection() {