54 lines
1.4 KiB
Rust
54 lines
1.4 KiB
Rust
use std::ops::Add;
|
|
|
|
struct RangeFinder<'a, T: 'a> {
|
|
index: usize,
|
|
length: usize,
|
|
arr: &'a [T],
|
|
}
|
|
|
|
impl<'a, T> Iterator for RangeFinder<'a, T> where T: PartialEq + Add<i8, Output=T> + Copy {
|
|
type Item = (T, Option<T>);
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
if self.index == self.length {
|
|
return None;
|
|
}
|
|
let lo = self.index;
|
|
while self.index < self.length - 1 && self.arr[self.index + 1] == self.arr[self.index] + 1 {
|
|
self.index += 1
|
|
}
|
|
let hi = self.index;
|
|
self.index += 1;
|
|
if hi - lo > 1 {
|
|
Some((self.arr[lo], Some(self.arr[hi])))
|
|
} else {
|
|
if hi - lo == 1 {
|
|
self.index -= 1
|
|
}
|
|
Some((self.arr[lo], None))
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a, T> RangeFinder<'a, T> {
|
|
fn new(a: &'a [T]) -> Self {
|
|
RangeFinder {
|
|
index: 0,
|
|
arr: a,
|
|
length: a.len(),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let input_numbers : &[i8] = &[0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
|
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
|
25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
|
|
37, 38, 39];
|
|
for (i, (lo, hi)) in RangeFinder::new(&input_numbers).enumerate() {
|
|
if i > 0 {print!(",")}
|
|
print!("{}", lo);
|
|
if hi.is_some() {print!("-{}", hi.unwrap())}
|
|
}
|
|
println!("");
|
|
}
|