1use std::fmt;
2use std::cmp;
3
4use std::str::FromStr;
5
6#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
11pub struct Interval(u32, u32);
12
13#[derive(Clone, Debug, Eq, PartialEq)]
16pub struct IntervalSet {
17 intervals: Vec<Interval>,
18}
19
20pub struct IntervalSetIterator<'a> {
22 pos: usize,
23 inner: &'a IntervalSet,
24}
25
26impl<'a> Iterator for IntervalSetIterator<'a> {
27 type Item = &'a Interval;
28
29 fn next(&mut self) -> Option<Self::Item> {
30 if self.pos >= self.inner.intervals.len() {
31 None
32 } else {
33 self.pos += 1;
34 self.inner.intervals.get(self.pos - 1)
35 }
36 }
37}
38
39impl Interval {
40 pub fn new(begin: u32, end: u32) -> Interval {
41 let res = Interval(begin, end);
42 if !res.is_valid() {
43 panic!("Call constructor of Interval with invalid endpoints: Interval({}, {})",
44 begin,
45 end);
46 }
47 res
48 }
49
50 pub fn whole() -> Interval {
52 Interval(u32::min_value(), u32::max_value())
53 }
54
55 pub fn range_size(&self) -> u32 {
58 self.1 - self.0 + 1
59 }
60
61 pub fn as_tuple(&self) -> (u32, u32) {
63 (self.0, self.1)
64 }
65
66 pub fn get_inf(&self) -> u32 {
69 self.0
70 }
71
72 pub fn get_sup(&self) -> u32 {
73 self.1
74 }
75
76 pub fn is_valid(&self) -> bool {
94 self.0 <= self.1
95 }
96}
97
98pub trait ToIntervalSet {
100 fn to_interval_set(self) -> IntervalSet;
102}
103
104impl ToIntervalSet for Interval {
105 fn to_interval_set(self) -> IntervalSet {
108 if self.is_valid() {
109 IntervalSet { intervals: vec![self] }
110 } else {
111 panic!("CReate interval set from an unvalid interval");
112 }
113 }
114}
115
116impl ToIntervalSet for Vec<Interval> {
117 fn to_interval_set(self) -> IntervalSet {
128 let mut res: IntervalSet = IntervalSet::empty();
129 for intv in self {
130 if !intv.is_valid() {
131 panic!("Invalid interval: {}-{}", intv.0, intv.1)
132 }
133 res.insert(intv);
134 }
135 res
136 }
137}
138
139impl ToIntervalSet for Vec<(u32, u32)> {
140 fn to_interval_set(self) -> IntervalSet {
150 let mut res: IntervalSet = IntervalSet::empty();
151 for (begin, end) in self {
152 if begin > end {
153 panic!("Invalid interval: {}-{}", begin, end)
154 }
155 res.insert(Interval(begin, end));
156 }
157 res
158 }
159}
160
161impl ToIntervalSet for String {
162 fn to_interval_set(self) -> IntervalSet {
192 let mut iter = self.split_whitespace();
193 let mut result = IntervalSet::empty();
194 for interval in iter {
195 if interval.contains("-") {
197 let bounds: Vec<u32> =
199 interval.split('-').map(|b| u32::from_str(b).unwrap()
200 ).collect();
201
202 let interval = Interval::new(bounds[0], bounds[1]);
203 result = result.union(interval.to_interval_set());
204 } else {
205 let bound = u32::from_str(interval).unwrap();
206 result = result.union(Interval::new(bound, bound).to_interval_set());
207 }
208 }
209 result
210 }
211}
212
213impl IntervalSet {
214 pub fn empty() -> IntervalSet {
216 IntervalSet { intervals: vec![] }
217 }
218
219 pub fn is_empty(&self) -> bool {
221 self.intervals.len() == 0
222 }
223
224 pub fn union(self, rhs: IntervalSet) -> IntervalSet {
236 self.merge(rhs, &|a, b| -> bool { a | b })
237 }
238
239 pub fn intersection(self, rhs: IntervalSet) -> IntervalSet {
251 self.merge(rhs, &|a, b| -> bool { a & b })
252 }
253
254 pub fn difference(self, rhs: IntervalSet) -> IntervalSet {
266 self.merge(rhs, &|a, b| -> bool { a & !b })
267 }
268
269 pub fn symetric_difference(self, rhs: IntervalSet) -> IntervalSet {
281 self.merge(rhs, &|a, b| -> bool { a ^ b })
282 }
283
284 pub fn max(&self) -> Option<Interval> {
306 let mut max = usize::min_value();
307 let mut res = None;
308
309 if self.is_empty() {
310 return None;
311 }
312
313 for intv in self.iter() {
314 let curr_: usize = (intv.1 - intv.0) as usize;
315 if curr_ > max {
316 max = curr_ as usize;
317 res = Some(intv.clone());
318 }
319 }
320 res
321 }
322
323 pub fn size(&self) -> u32 {
337 if self.is_empty() {
338 return 0;
339 }
340 self.iter().fold(0, |acc, ref x| acc + (x.range_size()))
341 }
342
343 pub fn iter<'a>(&'a self) -> IntervalSetIterator<'a> {
358 IntervalSetIterator {
359 inner: self,
360 pos: 0,
361 }
362 }
363
364 fn merge(self, rhs: IntervalSet, keep_operator: &Fn(bool, bool) -> bool) -> IntervalSet {
367 if self.is_empty() & rhs.is_empty() {
368 return self;
369 }
370
371 let mut lflat = self.flatten();
372 let mut rflat = rhs.flatten();
373
374 let sentinel: u32 = *cmp::max(lflat.iter().max(), rflat.iter().max()).unwrap() + 1;
375
376 lflat.push(sentinel);
377 rflat.push(sentinel);
378
379 let mut ltail = lflat.iter().enumerate();
380 let mut rtail = rflat.iter().enumerate();
381
382 let mut res = vec![];
383
384 let mut scan: u32 = *cmp::min(lflat.iter().min(), rflat.iter().min()).unwrap();
386
387 let mut lhead = ltail.next().unwrap();
388 let mut rhead = rtail.next().unwrap();
389
390 while scan < sentinel {
391 let lin = !((scan < *lhead.1) ^ (lhead.0 % 2 != 0));
392 let rin = !((scan < *rhead.1) ^ (rhead.0 % 2 != 0));
393
394 let inres = keep_operator(lin, rin);
395
396 if inres ^ (res.len() % 2 != 0) {
397 res.push(scan);
398 }
399
400 if scan == *lhead.1 {
401 lhead = match ltail.next() {
402 Some((lpos, lval)) => (lpos, lval),
403 _ => panic!("Deal with it braw"),
404 };
405 }
406 if scan == *rhead.1 {
407 rhead = match rtail.next() {
408 Some(rval) => rval,
409 _ => panic!("Deal with it braw"),
410 };
411 }
412 scan = cmp::min(*lhead.1, *rhead.1);
413 }
414 IntervalSet::unflatten(res)
415 }
416
417 fn flatten(self) -> Vec<u32> {
421 let mut res = vec![];
422 for intv in self.intervals {
423 res.extend(vec![intv.0, intv.1 + 1]);
424 }
425 res
426 }
427
428 fn unflatten(vec: Vec<u32>) -> IntervalSet {
430 let mut res: Vec<Interval> = Vec::new();
431 let mut i = 0;
432 while i < vec.len() {
433 res.push(Interval(vec[i], vec[i + 1] - 1));
434 i += 2;
435 }
436 res.to_interval_set()
437 }
438
439 pub fn insert(&mut self, element: Interval) {
440 let mut newinf = element.0;
441 let mut newsup = element.1;
442
443 let mut idx_shift = 0;
446 for (pos, intv) in self.intervals.clone().iter().enumerate() {
447 if newinf > intv.1 + 1 {
448 continue;
449 }
450 if newsup + 1 < intv.0 {
451 break;
452 }
453
454 self.intervals.remove(pos - idx_shift);
455 idx_shift += 1;
456
457 newinf = cmp::min(newinf, intv.0);
458 newsup = cmp::max(newsup, intv.1);
459 }
460 self.intervals.push(Interval::new(newinf, newsup));
461 self.intervals.sort();
462 }
463}
464
465impl fmt::Display for Interval {
466 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
467 if self.0 == self.1 {
468 write!(f, "{}", self.0)
469 } else {
470 write!(f, "{}-{}", self.0, self.1)
471 }
472 }
473}
474
475impl fmt::Display for IntervalSet {
476 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
477 for (pos, interval) in self.intervals.iter().enumerate() {
478 if pos == self.intervals.len() - 1 {
479 f.write_fmt(format_args!("{}", interval))?;
480 } else {
481 f.write_fmt(format_args!("{} ", interval))?;
482 }
483 }
484 write!(f, "")
485 }
486}
487
488#[cfg(test)]
489mod tests {
490 use super::*;
491
492 #[test]
493 fn test_print() {
494 let empty_set = IntervalSet::empty();
495 assert_eq!(format!("{}", empty_set), "");
496 }
497
498 fn assert_to_interval_set(tes_id: u32, v: Vec<(u32, u32)>, expected: IntervalSet) {
499 assert_eq!(v.to_interval_set(), expected, "Test {} failed", tes_id);
500 }
501
502 #[test]
503 fn test_to_interval_set() {
504 let sym_cases =
505 vec![(1, vec![(5, 10)], IntervalSet { intervals: vec![Interval(5, 10)] }),
506 (2, vec![(0, 100), (5, 10)], IntervalSet { intervals: vec![Interval(0, 100)] }),
507 (3,
508 vec![(1, 1), (2, 2), (3, 3), (4, 10), (10, 20)],
509 IntervalSet { intervals: vec![Interval(1, 20)] })];
510
511 for (id, v, expected) in sym_cases {
512 assert_to_interval_set(id, v, expected);
514 }
515 }
516
517 fn assert_insertion(tes_id: u32, a: IntervalSet, element: Interval, expected: IntervalSet) {
518 let mut a_ = a.clone();
519 a_.insert(element);
520 assert_eq!(a_, expected, "Test {} failed", tes_id);
521 }
522
523 #[test]
524 fn test_insertion() {
525 let sym_cases: Vec<(u32, IntervalSet, Interval, IntervalSet)> =
526 vec![(1,
527 IntervalSet { intervals: vec![Interval(0, 0)] },
528 Interval(1, 1),
529 IntervalSet { intervals: vec![Interval(0, 1)] }),
530 (2,
531 IntervalSet { intervals: vec![Interval(0, 0), Interval(2, 2)] },
532 Interval(1, 1),
533 IntervalSet { intervals: vec![Interval(0, 2)] }),
534 (3,
535 IntervalSet { intervals: vec![Interval(0, 3)] },
536 Interval(1, 1),
537 IntervalSet { intervals: vec![Interval(0, 3)] }),
538 (4,
539 IntervalSet { intervals: vec![Interval(1, 1)] },
540 Interval(0, 3),
541 IntervalSet { intervals: vec![Interval(0, 3)] }),
542 (5,
543 IntervalSet { intervals: vec![Interval(0, 100)] },
544 Interval(1, 3),
545 IntervalSet { intervals: vec![Interval(0, 100)] }),
546 (6,
547 IntervalSet { intervals: vec![Interval(10, 20)] },
548 Interval(40, 80),
549 IntervalSet { intervals: vec![Interval(10, 20), Interval::new(40, 80)] })];
550
551 for (id, a, element, expected) in sym_cases {
552 assert_insertion(id, a, element, expected);
554 }
555 }
556
557 #[test]
558 fn test_flatten() {
559 let simple_range = vec![Interval(0, 10)].to_interval_set();
560 let disjoint = vec![Interval(0, 10), Interval(15, 20)].to_interval_set();
561 assert_eq!(simple_range.flatten(), vec![0, 11]);
562 assert_eq!(disjoint.flatten(), vec![0, 11, 15, 21]);
563 }
564
565 #[test]
566 fn test_unflatten() {
567 let simple_range = vec![0, 11];
568 let disjoint = vec![0, 11, 15, 21];
569 assert_eq!(IntervalSet::unflatten(disjoint),
570 vec![Interval(0, 10), Interval(15, 20)].to_interval_set());
571 assert_eq!(IntervalSet::unflatten(simple_range),
572 vec![Interval(0, 10)].to_interval_set());
573 }
574
575 fn assert_difference(tes_id: u32, a: IntervalSet, b: IntervalSet, expected: IntervalSet) {
576 assert_eq!(a.difference(b), expected, "Test {} failed", tes_id);
577 }
578
579 #[test]
580 fn test_difference() {
581 let sym_cases: Vec<(u32, IntervalSet, IntervalSet, IntervalSet)> =
582 vec![(1,
583 vec![Interval(5, 10)].to_interval_set(),
584 vec![Interval(5, 10), Interval(15, 20)].to_interval_set(),
585 IntervalSet::empty()),
586 (2,
587 vec![(5, 10)].to_interval_set(),
588 vec![(5, 10), (15, 20)].to_interval_set(),
589 IntervalSet::empty()),
590 (3,
591 IntervalSet::empty(),
592 vec![(5, 10), (15, 20)].to_interval_set(),
593 IntervalSet::empty()),
594 (4,
595 vec![(5, 10), (15, 20)].to_interval_set(),
596 IntervalSet::empty(),
597 vec![(5, 10), (15, 20)].to_interval_set()),
598 (5,
599 vec![(0, 100)].to_interval_set(),
600 vec![(5, 10), (15, 20)].to_interval_set(),
601 vec![(0, 4), (11, 14), (21, 100)].to_interval_set()),
602 (6,
603 vec![(5, 10), (15, 20)].to_interval_set(),
604 vec![(0, 100)].to_interval_set(),
605 IntervalSet::empty()),
606 (7, IntervalSet::empty(), IntervalSet::empty(), IntervalSet::empty())];
607
608 for (id, a, b, expected) in sym_cases {
609 assert_difference(id, a, b, expected);
611 }
612 }
613
614 fn assert_intersection(tes_id: u32, a: IntervalSet, b: IntervalSet, expected: IntervalSet) {
615 assert_eq!(a.intersection(b), expected, "Test {} failed", tes_id);
616 }
617
618 #[test]
619 fn test_intersection() {
620 let sym_cases: Vec<(u32, IntervalSet, IntervalSet, IntervalSet)> =
621 vec![(1,
622 vec![Interval(5, 10)].to_interval_set(),
623 vec![Interval(5, 10), Interval(15, 20)].to_interval_set(),
624 vec![Interval(5, 10)].to_interval_set()),
625 (2,
626 vec![(5, 10)].to_interval_set(),
627 vec![(5, 10), (15, 20)].to_interval_set(),
628 vec![(5, 10)].to_interval_set()),
629 (3,
630 IntervalSet::empty(),
631 vec![(5, 10), (15, 20)].to_interval_set(),
632 IntervalSet::empty()),
633 (4,
634 vec![(5, 10), (15, 20)].to_interval_set(),
635 IntervalSet::empty(),
636 IntervalSet::empty()),
637 (5,
638 vec![(0, 100)].to_interval_set(),
639 vec![(5, 10), (15, 20)].to_interval_set(),
640 vec![(5, 10), (15, 20)].to_interval_set()),
641 (6, IntervalSet::empty(), IntervalSet::empty(), IntervalSet::empty())];
642
643 for (id, a, b, expected) in sym_cases {
644 assert_intersection(id, a, b, expected);
646 }
647 }
648
649 fn assert_union(tes_id: u32, a: IntervalSet, b: IntervalSet, expected: IntervalSet) {
650 assert_eq!(a.union(b), expected, "Test {} failed", tes_id);
651 }
652
653 #[test]
654 fn test_union() {
655 let sym_cases: Vec<(u32, IntervalSet, IntervalSet, IntervalSet)> =
659 vec![(1,
660 vec![Interval(5, 10)].to_interval_set(),
661 vec![Interval(5, 10), Interval(15, 20)].to_interval_set(),
662 vec![Interval(5, 10), Interval(15, 20)].to_interval_set()),
663 (2,
664 vec![(5, 10)].to_interval_set(),
665 vec![(5, 10), (15, 20)].to_interval_set(),
666 vec![(5, 10), (15, 20)].to_interval_set()),
667 (3,
668 IntervalSet::empty(),
669 vec![(5, 10), (15, 20)].to_interval_set(),
670 vec![(5, 10), (15, 20)].to_interval_set()),
671 (4,
672 vec![(5, 10), (15, 20)].to_interval_set(),
673 IntervalSet::empty(),
674 vec![(5, 10), (15, 20)].to_interval_set()),
675 (5,
676 vec![(0, 100)].to_interval_set(),
677 vec![(5, 10), (15, 20)].to_interval_set(),
678 vec![(0, 100)].to_interval_set()),
679 (6, IntervalSet::empty(), IntervalSet::empty(), IntervalSet::empty()),
680 (7,
681 vec![(0, 0), (2, 2), (3, 3)].to_interval_set(),
682 vec![(1, 1)].to_interval_set(),
683 vec![(0, 3)].to_interval_set())];
684
685 for (id, a, b, expected) in sym_cases {
686 assert_union(id, a, b, expected);
688 }
689 }
690
691 fn assert_symetric_difference(tes_id: u32,
692 a: IntervalSet,
693 b: IntervalSet,
694 expected: IntervalSet) {
695 assert_eq!(a.symetric_difference(b), expected, "Test {} failed", tes_id);
696 }
697
698 #[test]
699 fn test_symetric_difference() {
700 let sym_cases: Vec<(u32, IntervalSet, IntervalSet, IntervalSet)> =
701 vec![(1,
702 vec![Interval(5, 10)].to_interval_set(),
703 vec![Interval(5, 10), Interval(15, 20)].to_interval_set(),
704 vec![(15, 20)].to_interval_set()),
705 (2,
706 vec![(5, 10)].to_interval_set(),
707 vec![(5, 10), (15, 20)].to_interval_set(),
708 vec![(15, 20)].to_interval_set()),
709 (3,
710 IntervalSet::empty(),
711 vec![(5, 10), (15, 20)].to_interval_set(),
712 vec![(5, 10), (15, 20)].to_interval_set()),
713 (4,
714 vec![(5, 10), (15, 20)].to_interval_set(),
715 IntervalSet::empty(),
716 vec![(5, 10), (15, 20)].to_interval_set()),
717 (5,
718 vec![(0, 100)].to_interval_set(),
719 vec![(5, 10), (15, 20)].to_interval_set(),
720 vec![(0, 4), (11, 14), (21, 100)].to_interval_set()),
721 (6,
722 vec![(5, 10), (15, 20)].to_interval_set(),
723 vec![(0, 100)].to_interval_set(),
724 vec![(0, 4), (11, 14), (21, 100)].to_interval_set()),
725 (7, IntervalSet::empty(), IntervalSet::empty(), IntervalSet::empty())];
726
727 for (id, a, b, expected) in sym_cases {
728 assert_symetric_difference(id, a, b, expected);
730 }
731 }
732}