Created
October 18, 2022 10:32
-
-
Save raine/151264e21f3438bf1f68302597d1a630 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use itertools::Itertools; | |
use std::fmt; | |
#[derive(Debug)] | |
struct Range { | |
start: i32, | |
end: i32, | |
} | |
impl Range { | |
fn new(start: i32, end: i32) -> Self { | |
Range { start, end } | |
} | |
fn steps(&self) -> i32 { | |
self.end - self.start | |
} | |
} | |
impl fmt::Display for Range { | |
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
if self.start == self.end { | |
write!(f, "{}", self.start) | |
} else { | |
write!(f, "{}-{}", self.start, self.end) | |
} | |
} | |
} | |
pub fn range_extraction(ints: &[i32]) -> String { | |
// Construct Ranges for ints so that consecutive numbers belong to the same Range | |
let ranges: Vec<Range> = ints | |
.iter() | |
.fold(Vec::new(), |mut acc, n| match acc.last_mut() { | |
Some(mut prev) if prev.end + 1 == *n => { | |
prev.end = *n; | |
acc | |
} | |
Some(_) | None => { | |
acc.push(Range::new(*n, *n)); | |
acc | |
} | |
}); | |
ranges | |
.into_iter() | |
// For ranges that don't span 3 numbers, map them to Ranges that consist of a single number | |
.flat_map(|range| { | |
if range.steps() >= 2 { | |
vec![range] | |
} else { | |
(range.start..=range.end) | |
.map(|n| Range::new(n, n)) | |
.collect() | |
} | |
}) | |
.map(|range| format!("{}", range)) | |
.join(",") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment