flag_algebra/
iterators.rs

1//! Streaming iterators on combinatorial objects (subsets, functions, ...).
2//!
3//! All these iterators works without allocating new memory after
4//! their initialisation.
5///
6/// Interface for streaming iterators.
7///
8/// Similarly as in the streaming-iterator crate, the elements yielded by the iterator
9/// are borrowed by the iterator.
10/// A loop on such an iterator `iter` is written as follows.
11///```ignore
12///while let Some(item) = iter.next() {
13///    ...
14///}
15///```
16
17pub trait StreamingIterator<A>
18where
19    A: ?Sized,
20{
21    /// Return the next value of the iterator.
22    fn next(&mut self) -> Option<&A>;
23}
24
25/// Iterator on subsets of `[n]`.
26#[derive(Clone, Debug)]
27pub struct Subsets {
28    n: usize,
29    data: Vec<usize>,
30    untouched: bool,
31}
32
33impl Subsets {
34    /// Create an iterator on the subsets of `[n]`.
35    pub fn new(n: usize) -> Self {
36        Self {
37            n,
38            data: Vec::with_capacity(n),
39            untouched: true,
40        }
41    }
42}
43
44impl StreamingIterator<[usize]> for Subsets {
45    fn next(&mut self) -> Option<&[usize]> {
46        if self.untouched {
47            //skip the first step
48            self.untouched = false;
49        } else {
50            let mut k = self.n;
51            loop {
52                if k == 0 {
53                    return None;
54                }
55                k -= 1;
56                if self.data.last() != Some(&k) {
57                    break;
58                }
59                let _ = self.data.pop();
60            }
61            self.data.push(k);
62        }
63        Some(&self.data)
64    }
65}
66
67/// Iterator on functions from [n] to [k].
68#[derive(Clone, Debug)]
69pub struct Functions {
70    n: usize,
71    k: usize,
72    data: Vec<usize>,
73    untouched: bool,
74}
75
76impl Functions {
77    /// Create an iterator on the function from `[n]` to `[k]`.
78    pub fn new(n: usize, k: usize) -> Self {
79        Self {
80            n,
81            k,
82            data: vec![0; n],
83            untouched: true,
84        }
85    }
86}
87
88impl StreamingIterator<[usize]> for Functions {
89    fn next(&mut self) -> Option<&[usize]> {
90        if self.untouched {
91            //skip the first step
92            self.untouched = false;
93        } else {
94            let mut i = 0;
95            while i < self.n && self.data[i] == self.k - 1 {
96                i += 1;
97            }
98            if i == self.n {
99                return None;
100            } else {
101                self.data[i] += 1;
102                for j in 0..i {
103                    self.data[j] = 0;
104                }
105            }
106        }
107        Some(&self.data)
108    }
109}
110
111/// Iterator on subsets of [n] with `k` elements represented by
112/// an increasing array.
113#[derive(Clone, Debug)]
114pub struct Choose {
115    n: usize,     // total number of elements
116    k: usize,     // number of elements chosen
117    fixed: usize, // number of elements fixed
118    data: Vec<usize>,
119    untouched: bool,
120}
121
122impl Choose {
123    /// Subsets of [n] with k elements.
124    pub fn new(n: usize, k: usize) -> Self {
125        Self::with_fixed_part(n, k, 0)
126    }
127    /// Subsets of [n] with k elements that contain [fixed].  
128    pub fn with_fixed_part(n: usize, k: usize, fixed: usize) -> Self {
129        assert!(fixed <= k && k <= n);
130        Self {
131            n,
132            k,
133            fixed,
134            data: (0..k).collect(),
135            untouched: true,
136        }
137    }
138}
139
140impl StreamingIterator<[usize]> for Choose {
141    fn next(&mut self) -> Option<&[usize]> {
142        if self.untouched {
143            self.untouched = false;
144        } else {
145            let mut i = self.k;
146            loop {
147                if i <= self.fixed {
148                    return None;
149                } else {
150                    i -= 1
151                };
152                if self.data[i] != self.n - self.k + i {
153                    break;
154                }
155            }
156            self.data[i] += 1;
157            for j in (i + 1)..self.k {
158                self.data[j] = self.data[i] + j - i;
159            }
160        }
161        Some(&self.data)
162    }
163}
164
165/// Iterator on the partitions of [n] into two sets of respective size `k` and `n-k`.
166#[derive(Clone, Debug)]
167pub struct Split {
168    choose: Choose,
169    second_part: Vec<usize>,
170}
171
172impl Split {
173    /// Create an iterator on partitions of [n] into two sets of respective size `k` and `n-k`.
174    #[allow(unused)]
175    pub fn new(n: usize, k: usize) -> Self {
176        Self::with_fixed_part(n, k, 0)
177    }
178    /// Create an iterator on partitions of [n] into two sets of respective size `k`
179    /// and `n-k+fixed` that both contain `[fixed]`.
180    pub fn with_fixed_part(n: usize, k: usize, fixed: usize) -> Self {
181        let second_part_size = n - k + fixed;
182        Self {
183            choose: Choose::with_fixed_part(n, k, fixed),
184            second_part: (0..second_part_size).collect(),
185        }
186    }
187    /// Yield next element of the iterator.
188    ///
189    /// Because of the type of this function, `Split` does not implement
190    /// the trait `StreamingIterator`.
191    pub fn next(&mut self) -> Option<(&[usize], &[usize])> {
192        let fixed = self.choose.fixed;
193        let k = self.choose.k;
194        let n = self.choose.n;
195        match self.choose.next() {
196            Some(p) => {
197                let mut j = fixed;
198                for i in fixed..=k {
199                    let start = if i == fixed { fixed } else { p[i - 1] + 1 };
200                    let end = if i == k { n } else { p[i] };
201                    for v in start..end {
202                        self.second_part[j] = v;
203                        j += 1;
204                    }
205                }
206                Some((p, &self.second_part))
207            }
208            None => None,
209        }
210    }
211}
212
213/// Iterator on the injections from [k] to [n].
214#[derive(Clone, Debug)]
215pub struct Injection {
216    n: usize,
217    k: usize,
218    data: Vec<usize>,
219    index: Vec<usize>,
220    fixed: usize, // number of fixed elements
221    untouched: bool,
222}
223
224impl Injection {
225    /// Iterator on the injections from `[k]` to `[n]` that stabilize `[fixed]`.
226    pub fn with_fixed_part(n: usize, k: usize, fixed: usize) -> Self {
227        assert!(k <= n);
228        assert!(fixed <= k);
229        Self {
230            n,
231            k,
232            data: (0..n).collect(),
233            index: (0..k).collect(),
234            fixed,
235            untouched: true,
236        }
237    }
238
239    /// Iterator on the injections from [k] to [n].
240    pub fn new(n: usize, k: usize) -> Self {
241        Self::with_fixed_part(n, k, 0)
242    }
243
244    ///Iterator on the permutations of [n].
245    pub fn permutation(n: usize) -> Self {
246        Self::new(n, n)
247    }
248
249    #[inline]
250    fn set_index(&mut self, i: usize, val: usize) {
251        let old_val = self.index[i];
252        self.index[i] = val;
253        self.data.swap(i, old_val);
254        self.data.swap(i, val);
255    }
256}
257
258impl StreamingIterator<[usize]> for Injection {
259    fn next(&mut self) -> Option<&[usize]> {
260        if self.untouched {
261            self.untouched = false;
262        } else {
263            if self.k == self.fixed {
264                return None;
265            }; // Avoiding negative value on next line
266            let mut i = self.k - 1;
267            while self.index[i] == self.n - 1 {
268                if i == self.fixed {
269                    return None;
270                };
271                i -= 1
272            }
273            let vi = self.index[i] + 1;
274            self.set_index(i, vi);
275            for j in (i + 1)..self.k {
276                self.set_index(j, j);
277            }
278        }
279        Some(&self.data[0..self.k])
280    }
281}
282
283///Tests
284#[cfg(test)]
285mod tests {
286    use super::*;
287
288    fn count<I, T>(mut iterator: I) -> usize
289    where
290        I: StreamingIterator<T>,
291        T: ?Sized,
292    {
293        let mut count = 0;
294        while iterator.next().is_some() {
295            count += 1;
296        }
297        count
298    }
299
300    #[test]
301    fn unit_subsets() {
302        assert_eq!(1, count(Subsets::new(0)));
303        assert_eq!(2, count(Subsets::new(1)));
304        assert_eq!(16, count(Subsets::new(4)));
305    }
306
307    #[test]
308    fn unit_choose() {
309        assert_eq!(120, count(Choose::new(10, 3)));
310        assert_eq!(3, count(Choose::new(3, 1)));
311        assert_eq!(1, count(Choose::new(0, 0)));
312        assert_eq!(1, count(Choose::new(2, 2)));
313        assert_eq!(120, count(Choose::with_fixed_part(11, 4, 1)));
314        assert_eq!(1, count(Choose::with_fixed_part(5, 5, 4)));
315        assert_eq!(1, count(Choose::with_fixed_part(4, 4, 4)));
316        assert_eq!(1, count(Choose::with_fixed_part(6, 2, 2)));
317        assert_eq!(1, count(Choose::with_fixed_part(0, 0, 0)));
318    }
319
320    #[test]
321    fn unit_split() {
322        let mut iter = Split::with_fixed_part(12, 5, 2);
323        let mut count = 0;
324        while let Some((_a, _b)) = iter.next() {
325            count += 1;
326        }
327        assert_eq!(120, count);
328    }
329
330    #[test]
331    fn unit_injection() {
332        assert_eq!(60, count(Injection::new(5, 3)));
333        assert_eq!(1, count(Injection::new(42, 0)));
334        assert_eq!(720, count(Injection::permutation(6)));
335        assert_eq!(20, count(Injection::with_fixed_part(8, 5, 3)));
336        assert_eq!(1, count(Injection::with_fixed_part(6, 2, 2)));
337        assert_eq!(1, count(Injection::new(0, 0)));
338    }
339}