1pub trait StreamingIterator<A>
18where
19 A: ?Sized,
20{
21 fn next(&mut self) -> Option<&A>;
23}
24
25#[derive(Clone, Debug)]
27pub struct Subsets {
28 n: usize,
29 data: Vec<usize>,
30 untouched: bool,
31}
32
33impl Subsets {
34 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 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#[derive(Clone, Debug)]
69pub struct Functions {
70 n: usize,
71 k: usize,
72 data: Vec<usize>,
73 untouched: bool,
74}
75
76impl Functions {
77 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 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#[derive(Clone, Debug)]
114pub struct Choose {
115 n: usize, k: usize, fixed: usize, data: Vec<usize>,
119 untouched: bool,
120}
121
122impl Choose {
123 pub fn new(n: usize, k: usize) -> Self {
125 Self::with_fixed_part(n, k, 0)
126 }
127 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#[derive(Clone, Debug)]
167pub struct Split {
168 choose: Choose,
169 second_part: Vec<usize>,
170}
171
172impl Split {
173 #[allow(unused)]
175 pub fn new(n: usize, k: usize) -> Self {
176 Self::with_fixed_part(n, k, 0)
177 }
178 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 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#[derive(Clone, Debug)]
215pub struct Injection {
216 n: usize,
217 k: usize,
218 data: Vec<usize>,
219 index: Vec<usize>,
220 fixed: usize, untouched: bool,
222}
223
224impl Injection {
225 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 pub fn new(n: usize, k: usize) -> Self {
241 Self::with_fixed_part(n, k, 0)
242 }
243
244 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 }; 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#[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}