Challenge 53
Merge Intervals
Write a function merge_intervals
that takes a vector of intervals (each interval is a tuple (i32, i32)) and returns a new vector with all overlapping intervals merged.
Intervals are considered overlapping if one’s start time is less than or equal to another’s end time. The output should be sorted by start time.
Write your solution below
// Rust Bytes Challenge Issue #62: Merge Intervals pub fn merge_intervals(mut intervals: Vec<(i32, i32)>) -> Vec<(i32, i32)> { // your implementation goes here } #[cfg(test)] mod tests { use super::*; #[test] fn test_basic_overlap() { assert_eq!( merge_intervals(vec![(1, 3), (2, 6), (8, 10), (15, 18)]), vec![(1, 6), (8, 10), (15, 18)] ); } #[test] fn test_empty_vector() { assert_eq!(merge_intervals(vec![]), vec![]); } #[test] fn test_no_overlap() { assert_eq!( merge_intervals(vec![(1, 2), (3, 4), (5, 6)]), vec![(1, 2), (3, 4), (5, 6)] ); } #[test] fn test_all_overlapping() { assert_eq!(merge_intervals(vec![(1, 4), (2, 5), (3, 6)]), vec![(1, 6)]); } #[test] fn test_single_interval() { assert_eq!(merge_intervals(vec![(5, 10)]), vec![(5, 10)]); } #[test] fn test_negative_intervals() { assert_eq!( merge_intervals(vec![(-5, -2), (-3, 0), (1, 3)]), vec![(-5, 0), (1, 3)] ); } #[test] fn test_overlapping_with_same_start() { assert_eq!( merge_intervals(vec![(1, 5), (1, 3), (6, 8)]), vec![(1, 5), (6, 8)] ); } #[test] fn test_large_gaps() { assert_eq!( merge_intervals(vec![(1, 2), (10, 11), (20, 21)]), vec![(1, 2), (10, 11), (20, 21)] ); } #[test] fn test_nested_intervals() { assert_eq!( merge_intervals(vec![(1, 10), (2, 3), (4, 5), (7, 8)]), vec![(1, 10)] ); } #[test] fn test_adjacent_intervals() { assert_eq!(merge_intervals(vec![(1, 2), (2, 3), (3, 4)]), vec![(1, 4)]); } #[test] fn test_unsorted_input() { assert_eq!( merge_intervals(vec![(15, 18), (1, 3), (8, 10), (2, 6)]), vec![(1, 6), (8, 10), (15, 18)] ); } #[test] fn test_zero_length_intervals() { assert_eq!(merge_intervals(vec![(1, 1), (2, 2), (1, 3)]), vec![(1, 3)]); } }
Solution
Click to Show/Hide Solution
#![allow(unused)] fn main() { // Rust Bytes Challenge Issue #62: Merge Intervals pub fn merge_intervals(mut intervals: Vec<(i32, i32)>) -> Vec<(i32, i32)> { intervals.sort_unstable_by_key(|(s, _)| *s); let mut out = Vec::with_capacity(intervals.len()); for (start, end) in intervals { match out.last_mut() { Some((_, last_end)) => { if &start > last_end { out.push((start, end)); } else if &end > last_end { *last_end = end; } } None => out.push((start, end)), } } out } #[cfg(test)] mod tests { use super::*; #[test] fn test_basic_overlap() { assert_eq!( merge_intervals(vec![(1, 3), (2, 6), (8, 10), (15, 18)]), vec![(1, 6), (8, 10), (15, 18)] ); } #[test] fn test_empty_vector() { assert_eq!(merge_intervals(vec![]), vec![]); } #[test] fn test_no_overlap() { assert_eq!( merge_intervals(vec![(1, 2), (3, 4), (5, 6)]), vec![(1, 2), (3, 4), (5, 6)] ); } #[test] fn test_all_overlapping() { assert_eq!(merge_intervals(vec![(1, 4), (2, 5), (3, 6)]), vec![(1, 6)]); } #[test] fn test_single_interval() { assert_eq!(merge_intervals(vec![(5, 10)]), vec![(5, 10)]); } #[test] fn test_negative_intervals() { assert_eq!( merge_intervals(vec![(-5, -2), (-3, 0), (1, 3)]), vec![(-5, 0), (1, 3)] ); } #[test] fn test_overlapping_with_same_start() { assert_eq!( merge_intervals(vec![(1, 5), (1, 3), (6, 8)]), vec![(1, 5), (6, 8)] ); } #[test] fn test_large_gaps() { assert_eq!( merge_intervals(vec![(1, 2), (10, 11), (20, 21)]), vec![(1, 2), (10, 11), (20, 21)] ); } #[test] fn test_nested_intervals() { assert_eq!( merge_intervals(vec![(1, 10), (2, 3), (4, 5), (7, 8)]), vec![(1, 10)] ); } #[test] fn test_adjacent_intervals() { assert_eq!(merge_intervals(vec![(1, 2), (2, 3), (3, 4)]), vec![(1, 4)]); } #[test] fn test_unsorted_input() { assert_eq!( merge_intervals(vec![(15, 18), (1, 3), (8, 10), (2, 6)]), vec![(1, 6), (8, 10), (15, 18)] ); } #[test] fn test_zero_length_intervals() { assert_eq!(merge_intervals(vec![(1, 1), (2, 2), (1, 3)]), vec![(1, 3)]); } } }