1use std::cmp::Ordering::{self, *};
4use std::collections::BTreeSet;
5use std::fmt::Debug;
6use std::ops::{
7 Bound::{self, *},
8 RangeBounds,
9};
10
11#[derive(Clone, Debug, Eq)]
17struct Interval<T: Ord>(Bound<T>, Bound<T>);
18
19impl<T: Clone + Ord> From<(Bound<&T>, Bound<&T>)> for Interval<T> {
20 fn from(r: (Bound<&T>, Bound<&T>)) -> Interval<T> {
21 let s = match r.0 {
22 Included(lo) => Included(lo.clone()),
23 Excluded(lo) => Excluded(lo.clone()),
24 Unbounded => Unbounded,
25 };
26 let e = match r.1 {
27 Included(hi) => Included(hi.clone()),
28 Excluded(hi) => Excluded(hi.clone()),
29 Unbounded => Unbounded,
30 };
31 Interval(s, e)
32 }
33}
34
35impl<T: Ord> Interval<T> {
36 fn is_empty(&self) -> bool {
37 match (&self.0, &self.1) {
38 (Unbounded, _) | (_, Unbounded) => false,
39 (Included(lo), Included(hi)) => !(lo <= hi),
40 (Included(lo), Excluded(hi))
41 | (Excluded(lo), Included(hi))
42 | (Excluded(lo), Excluded(hi)) => !(lo < hi),
43 }
44 }
45 fn is_superset(&self, other: &Self) -> bool {
46 if other.is_empty() {
47 return true;
48 }
49 if self.is_empty() {
50 return false;
51 }
52
53 match (&self.0, &other.0) {
55 (Unbounded, _) => {}
56 (_, Unbounded) => return false,
57 (Excluded(lhs), Included(rhs)) if lhs == rhs => return false,
58 (Included(lhs), Included(rhs))
59 | (Included(lhs), Excluded(rhs))
60 | (Excluded(lhs), Included(rhs))
61 | (Excluded(lhs), Excluded(rhs))
62 if lhs > rhs =>
63 {
64 return false
65 }
66 _ => {}
67 }
68
69 match (&self.1, &other.1) {
71 (Unbounded, _) => true,
72 (_, Unbounded) => false,
73 (Excluded(lhs), Included(rhs)) => lhs > rhs,
74 (Included(lhs), Included(rhs))
75 | (Included(lhs), Excluded(rhs))
76 | (Excluded(lhs), Excluded(rhs)) => lhs >= rhs,
77 }
78 }
79 fn touches(&self, other: &Self) -> bool {
80 let (left, right) = match self.cmp(&other) {
81 Less => (&self, &other),
82 Equal => return true,
83 Greater => (&other, &self),
84 };
85 match (&left.1, &right.0) {
86 (Unbounded, _) | (_, Unbounded) => true,
87 (Included(le), Included(rs))
88 | (Included(le), Excluded(rs))
89 | (Excluded(le), Included(rs)) => rs <= le,
90 (Excluded(le), Excluded(rs)) => rs < le,
91 }
92 }
93}
94
95fn toggle_bound<T: Ord>(b: Bound<T>) -> Bound<T> {
96 match b {
97 Included(x) => Excluded(x),
98 Excluded(x) => Included(x),
99 Unbounded => Unbounded,
100 }
101}
102
103impl<T: Ord> Ord for Interval<T> {
104 fn cmp(&self, other: &Self) -> Ordering {
105 if self.is_empty() && other.is_empty() {
106 return Equal;
107 }
108 if self.0 != other.0 {
109 return match (&self.0, &other.0) {
110 (Unbounded, _) => Less,
111 (_, Unbounded) => Greater,
112 (Included(lhs), Excluded(rhs)) if lhs == rhs => Less,
113 (Excluded(lhs), Included(rhs)) if lhs == rhs => Greater,
114 (Included(lhs), Included(rhs))
115 | (Included(lhs), Excluded(rhs))
116 | (Excluded(lhs), Included(rhs))
117 | (Excluded(lhs), Excluded(rhs)) => lhs.cmp(rhs),
118 };
119 }
120 if self.1 != other.1 {
121 return match (&self.1, &other.1) {
122 (_, Unbounded) => Less,
123 (Unbounded, _) => Greater,
124 (Excluded(lhs), Included(rhs)) if lhs == rhs => Less,
125 (Included(lhs), Excluded(rhs)) if lhs == rhs => Greater,
126 (Included(lhs), Included(rhs))
127 | (Included(lhs), Excluded(rhs))
128 | (Excluded(lhs), Included(rhs))
129 | (Excluded(lhs), Excluded(rhs)) => lhs.cmp(rhs),
130 };
131 }
132 Equal
133 }
134}
135
136impl<T: Ord> PartialOrd for Interval<T> {
137 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
138 Some(self.cmp(other))
139 }
140}
141
142impl<T: Ord> PartialEq for Interval<T> {
143 fn eq(&self, other: &Self) -> bool { self.cmp(other) == Equal }
144}
145
146#[derive(Clone, Debug, Eq, PartialEq)]
150pub struct IntervalSet<T: Ord> {
151 buf: BTreeSet<Interval<T>>,
152}
153
154impl<T: Clone + Debug + Ord> IntervalSet<T> {
155 pub fn new() -> Self { Self { buf: BTreeSet::new() } }
157
158 pub fn is_empty(&self) -> bool { self.buf.is_empty() }
160
161 pub fn insert<R: RangeBounds<T>>(&mut self, r: R) {
163 let mut r: Interval<T> = (r.start_bound(), r.end_bound()).into();
164 if r.is_empty() {
165 return;
166 }
167 self.remove_subset(&r);
168 match self.buf.range(..&r).cloned().next_back() {
169 Some(x) if x.is_superset(&r) => return,
170 Some(x) if x.touches(&r) => {
171 self.buf.remove(&x);
172 r.0 = x.0;
173 }
174 _ => {}
175 }
176 match self.buf.range(&r..).cloned().next() {
177 Some(x) if x.touches(&r) => {
178 self.buf.remove(&x);
179 r.1 = x.1;
180 }
181 _ => {}
182 }
183 self.buf.insert(r);
184 }
185
186 fn insert_if_nonempty(&mut self, x: Interval<T>) {
187 if !x.is_empty() {
188 self.buf.insert(x);
189 }
190 }
191
192 pub fn remove<R: RangeBounds<T>>(&mut self, r: R) {
194 let r: Interval<T> = (r.start_bound(), r.end_bound()).into();
195 if r.is_empty() {
196 return;
197 }
198 self.remove_subset(&r);
199 match self.buf.range(..&r).cloned().next_back() {
200 Some(x) if x.is_superset(&r) => {
201 self.buf.remove(&x);
202 let Interval(r0, r1) = r;
203 self.insert_if_nonempty(Interval(x.0, toggle_bound(r0)));
204 self.insert_if_nonempty(Interval(toggle_bound(r1), x.1));
205 return;
206 }
207 Some(mut x) if x.touches(&r) => {
208 self.buf.remove(&x);
209 x.1 = toggle_bound(r.0.clone());
210 self.insert_if_nonempty(x);
211 }
212 _ => {}
213 }
214 match self.buf.range(&r..).cloned().next() {
215 Some(mut x) if x.touches(&r) => {
216 self.buf.remove(&x);
217 x.0 = toggle_bound(r.1);
218 self.insert_if_nonempty(x);
219 }
220 _ => {}
221 }
222 }
223
224 pub fn clear(&mut self) { self.buf.clear(); }
226
227 pub fn mex<'a>(&'a self, x: &'a T) -> Bound<&'a T> {
247 if self.buf.is_empty() {
248 return Included(&x);
249 }
250 match self
251 .buf
252 .range(..=Interval(Included(x.clone()), Unbounded))
253 .next_back()
254 {
255 Some(Interval(_, Included(y))) if y < x => Included(x),
256 Some(Interval(_, Included(y))) => Excluded(y),
257 Some(Interval(_, Excluded(y))) if y <= x => Included(x),
258 Some(Interval(_, Excluded(y))) => Included(y),
259 Some(Interval(_, Unbounded)) => Unbounded,
260 None => Included(x),
261 }
262 }
263
264 pub fn covering<R: RangeBounds<T>>(
266 &self,
267 r: &R,
268 ) -> Option<(&Bound<T>, &Bound<T>)> {
269 let r: Interval<T> = (r.start_bound(), r.end_bound()).into();
270 if self.buf.is_empty() {
271 return None;
272 }
273 (if r.is_empty() {
274 self.buf.range(..).next()
275 } else {
276 match self
277 .buf
278 .range(..=&Interval(r.0.clone(), Unbounded))
279 .next_back()
280 {
281 Some(s) if s.is_superset(&r) => Some(s),
282 _ => None,
283 }
284 })
285 .map(|r| (&r.0, &r.1))
286 }
287
288 pub fn has_range<R: RangeBounds<T>>(&self, r: &R) -> bool {
290 self.covering(r).is_some()
291 }
292
293 fn remove_subset(&mut self, r: &Interval<T>) {
294 let rem: Vec<Interval<T>> = match r {
295 Interval(Unbounded, Unbounded) => {
296 self.buf.clear();
297 return;
298 }
299 Interval(Included(lo), Unbounded)
300 | Interval(Excluded(lo), Unbounded) => self.buf.range((
301 Included(Interval(Included(lo.clone()), Included(lo.clone()))),
302 Unbounded,
303 )),
304 Interval(Unbounded, Included(hi))
305 | Interval(Unbounded, Excluded(hi)) => self.buf.range((
306 Unbounded,
307 Included(Interval(Included(hi.clone()), Included(hi.clone()))),
308 )),
309 Interval(Included(lo), Included(hi))
310 | Interval(Included(lo), Excluded(hi))
311 | Interval(Excluded(lo), Included(hi))
312 | Interval(Excluded(lo), Excluded(hi)) => self.buf.range((
313 Included(Interval(Included(lo.clone()), Included(lo.clone()))),
314 Included(Interval(Included(hi.clone()), Included(hi.clone()))),
315 )),
316 }
317 .cloned()
318 .collect();
319 for k in rem.into_iter().filter(|x| r.is_superset(x)) {
320 self.buf.remove(&k);
321 }
322 }
323
324 pub fn iter(
325 &self,
326 ) -> impl Iterator<Item = (&Bound<T>, &Bound<T>)> + DoubleEndedIterator + '_
327 {
328 self.buf.iter().map(|x| (&x.0, &x.1))
329 }
330}