1use std::cmp::min;
2use std::convert::TryInto;
3use std::iter::FusedIterator;
4
5#[derive(Debug, Clone)]
8pub struct IterCombinations<I, F, T>
9where
10 I: Iterator + Clone,
11 I::Item: Clone,
12 F: FnMut(&[I::Item]) -> T,
13{
14 base: std::iter::Peekable<std::iter::Enumerate<I>>,
15 iterators: Box<[std::iter::Peekable<std::iter::Enumerate<I>>]>,
16 done: bool,
17 converter: F,
18 buffer: Box<[I::Item]>,
19}
20
21impl<I, F, T> Iterator for IterCombinations<I, F, T>
22where
23 I: Iterator + Clone,
24 I::Item: Clone,
25 F: FnMut(&[I::Item]) -> T,
26{
27 type Item = T;
28
29 fn next(&mut self) -> Option<Self::Item> {
30 if self.done {
31 return None;
32 } else if self.iterators.is_empty() {
33 self.done = true;
34 return Some((self.converter)(&[]));
35 }
36 let result = (self.converter)(&self.buffer[..]);
37 for i in 0..self.iterators.len() - 1 {
38 let (its, next_its) = &mut self.iterators[i..i + 2].split_at_mut(1);
39 let (it, next_it) = (&mut its[0], &mut next_its[0]);
40 let can_forward = {
41 let (index, _) = it.peek().unwrap();
42 let (next_index, _) = next_it.peek().unwrap();
43 index + 1 < *next_index
44 };
45 if can_forward {
46 _ = it.next().unwrap();
47 self.buffer[i] = it.peek().unwrap().1.clone();
48 return Some(result);
49 } else {
50 *it = self.base.clone();
52 for _ in 0..i {
53 _ = it.next();
54 }
55 let (_, x) = it.peek().unwrap();
56 self.buffer[i] = x.clone();
57 }
58 }
59 if let Some(last_it) = self.iterators.last_mut() {
60 _ = last_it.next();
61 if let Some(x) = last_it.peek() {
62 *self.buffer.last_mut().unwrap() = x.1.clone();
63 } else {
64 self.done = true;
65 }
66 }
67 return Some(result);
68 }
69}
70
71impl<I, F, T> FusedIterator for IterCombinations<I, F, T>
72where
73 I: Iterator + Clone,
74 I::Item: Clone,
75 F: FnMut(&[I::Item]) -> T,
76{
77}
78
79pub fn combinations<I, F, T>(it: I, k: usize, converter: F) -> IterCombinations<I, F, T>
100where
101 I: Iterator + Clone,
102 I::Item: Clone,
103 F: FnMut(&[I::Item]) -> T,
104{
105 let enumerated_it = it.enumerate().peekable();
106 let mut start_iterators = Vec::with_capacity(k);
107 let mut buffer = Vec::with_capacity(k);
108 let mut start_it = enumerated_it.clone();
109 for _ in 0..k {
110 start_iterators.push(start_it.clone());
111 if start_it.peek().is_none() {
112 return IterCombinations {
113 base: enumerated_it,
114 iterators: start_iterators.into_boxed_slice(),
115 done: true,
116 converter,
117 buffer: buffer.into_boxed_slice(),
118 };
119 }
120 let (_, x) = start_it.next().unwrap();
121 buffer.push(x);
122 }
123 return IterCombinations {
124 base: enumerated_it,
125 iterators: start_iterators.into_boxed_slice(),
126 done: false,
127 converter,
128 buffer: buffer.into_boxed_slice(),
129 };
130}
131
132pub fn clone_slice<T>(slice: &[T]) -> Box<[T]>
134where
135 T: Clone,
136{
137 let vec: Vec<T> = slice.to_vec();
138 return vec.into_boxed_slice();
139}
140
141pub fn clone_array<T, const N: usize>(slice: &[T]) -> [T; N]
143where
144 T: Copy,
145{
146 slice.try_into().unwrap()
147}
148
149pub fn basic_combinations<I>(it: I, k: usize) -> impl Iterator<Item = Box<[I::Item]>>
156where
157 I: Iterator + Clone,
158 I::Item: Clone,
159{
160 combinations(it, k, clone_slice)
161}
162
163pub fn powerset<I, F, T>(it: I, converter: F) -> impl Iterator<Item = T>
167where
168 I: Iterator + Clone,
169 I::Item: Clone,
170 F: Clone + FnMut(&[I::Item]) -> T,
171{
172 let len = it.clone().count();
173 (0..=len).flat_map(move |i| combinations(it.clone(), i, converter.clone()))
174}
175
176pub fn basic_powerset<I>(it: I) -> impl Iterator<Item = Box<[I::Item]>>
183where
184 I: Iterator + Clone,
185 I::Item: Clone,
186{
187 powerset(it, clone_slice)
188}
189
190#[derive(Debug, Clone)]
193pub struct MultisetCombinations<'a, F, T>
194where
195 F: FnMut(&[usize]) -> T,
196{
197 converter: F,
198 superset: &'a [usize],
199 current: Option<Box<[usize]>>,
200 last_moved: usize,
201 first_trailing_empty: usize,
202}
203
204impl<'a, F, T> Iterator for MultisetCombinations<'a, F, T>
205where
206 F: FnMut(&[usize]) -> T,
207{
208 type Item = T;
209
210 fn next(&mut self) -> Option<T> {
211 let current = self.current.as_mut()?;
212 let result = (self.converter)(current);
213 let mut removed = 0;
214 let mut found_empty_place = self.last_moved + 1 < self.first_trailing_empty;
215 while !found_empty_place || current[self.last_moved] == 0 {
216 found_empty_place |= current[self.last_moved] < self.superset[self.last_moved];
217 removed += current[self.last_moved];
218 current[self.last_moved] = 0;
219 if self.last_moved == 0 {
220 self.current = None;
221 return Some(result);
222 }
223 self.last_moved -= 1;
224 }
225 removed += 1;
226 current[self.last_moved] -= 1;
227 while removed > 0 {
228 self.last_moved += 1;
229 if current[self.last_moved] + removed > self.superset[self.last_moved] {
230 removed = current[self.last_moved] + removed - self.superset[self.last_moved];
231 current[self.last_moved] = self.superset[self.last_moved];
232 } else {
233 current[self.last_moved] += removed;
234 removed = 0;
235 }
236 }
237 return Some(result);
238 }
239}
240
241impl<'a, F, T> FusedIterator for MultisetCombinations<'a, F, T> where F: FnMut(&[usize]) -> T {}
242
243pub fn multiset_combinations<'a, F, T>(
279 multiset: &'a [usize],
280 size: usize,
281 converter: F,
282) -> MultisetCombinations<'a, F, T>
283where
284 F: FnMut(&[usize]) -> T,
285{
286 assert!(!multiset.is_empty());
287 if size > multiset.iter().copied().sum::<usize>() {
288 return MultisetCombinations {
289 converter,
290 superset: multiset,
291 first_trailing_empty: 0,
292 current: None,
293 last_moved: 0,
294 };
295 }
296 let mut start = (0..multiset.len()).map(|_| 0).collect::<Vec<_>>().into_boxed_slice();
297 let mut to_insert = size;
298 let mut last_moved = 0;
299 let mut i = 0;
300 while to_insert > 0 {
301 start[i] = min(multiset[i], to_insert);
302 last_moved = i;
303 to_insert -= start[i];
304 i += 1;
305 }
306 let mut trailing_empty_entries = 0;
307 while trailing_empty_entries < multiset.len() && multiset[multiset.len() - trailing_empty_entries - 1] == 0 {
308 trailing_empty_entries += 1;
309 }
310 return MultisetCombinations {
311 converter,
312 superset: multiset,
313 first_trailing_empty: multiset.len() - trailing_empty_entries,
314 current: Some(start),
315 last_moved,
316 };
317}
318
319#[derive(Debug)]
322pub struct MultiProduct<I, F, G, T>
323where
324 I: Iterator + Clone,
325 F: FnMut(&[I::Item]) -> T,
326 G: Clone + Fn(usize, &I::Item) -> I::Item,
327{
328 base_iters: Vec<I>,
329 current_iters: Vec<I>,
330 current: Vec<I::Item>,
331 clone_el: G,
332 converter: F,
333 done: bool,
334}
335
336impl<I, F, G, T> Clone for MultiProduct<I, F, G, T>
337where
338 I: Iterator + Clone,
339 F: Clone + FnMut(&[I::Item]) -> T,
340 G: Clone + Fn(usize, &I::Item) -> I::Item,
341{
342 fn clone(&self) -> Self {
343 MultiProduct {
344 base_iters: self.base_iters.clone(),
345 current_iters: self.current_iters.clone(),
346 current: self
347 .current
348 .iter()
349 .enumerate()
350 .map(|(i, x)| (self.clone_el)(i, x))
351 .collect(),
352 clone_el: self.clone_el.clone(),
353 converter: self.converter.clone(),
354 done: self.done,
355 }
356 }
357}
358
359impl<I, F, G, T> Iterator for MultiProduct<I, F, G, T>
360where
361 I: Iterator + Clone,
362 F: FnMut(&[I::Item]) -> T,
363 G: Clone + Fn(usize, &I::Item) -> I::Item,
364{
365 type Item = T;
366
367 fn next(&mut self) -> Option<Self::Item> {
368 if self.done {
369 return None;
370 }
371 let result = (self.converter)(&self.current[..]);
372 let mut i = self.base_iters.len();
373 self.done = true;
374 while i > 0 {
375 i -= 1;
376 if let Some(val) = self.current_iters[i].next() {
377 self.current[i] = val;
378 self.done = false;
379 for j in (i + 1)..self.base_iters.len() {
380 self.current_iters[j] = self.base_iters[j].clone();
381 self.current[j] = self.current_iters[j].next().unwrap();
382 }
383 break;
384 }
385 }
386 return Some(result);
387 }
388}
389
390impl<I, F, G, T> FusedIterator for MultiProduct<I, F, G, T>
391where
392 I: Iterator + Clone,
393 F: Clone + FnMut(&[I::Item]) -> T,
394 G: Clone + Fn(usize, &I::Item) -> I::Item,
395{
396}
397
398pub fn multi_cartesian_product<J, F, G, T>(iters: J, converter: F, clone_el: G) -> MultiProduct<J::Item, F, G, T>
424where
425 J: Iterator,
426 J::Item: Iterator + Clone,
427 F: FnMut(&[<J::Item as Iterator>::Item]) -> T,
428 G: Clone + Fn(usize, &<J::Item as Iterator>::Item) -> <J::Item as Iterator>::Item,
429{
430 let base_iters = iters.collect::<Vec<_>>();
431 let mut current_iters = base_iters.clone();
432 let mut current = Vec::with_capacity(current_iters.len());
433 for it in current_iters.iter_mut() {
434 if let Some(v) = it.next() {
435 current.push(v);
436 } else {
437 return MultiProduct {
438 done: true,
439 converter,
440 base_iters,
441 clone_el,
442 current_iters,
443 current,
444 };
445 }
446 }
447 return MultiProduct {
448 done: false,
449 converter,
450 base_iters,
451 current_iters,
452 clone_el,
453 current,
454 };
455}
456
457#[derive(Debug)]
462pub struct CondenseIter<I, F, T>
463where
464 I: Iterator,
465 F: FnMut(I::Item) -> Option<T>,
466{
467 base_iter: I,
468 f: F,
469}
470
471impl<I, F, T> Iterator for CondenseIter<I, F, T>
472where
473 I: Iterator,
474 F: FnMut(I::Item) -> Option<T>,
475{
476 type Item = T;
477
478 fn next(&mut self) -> Option<T> {
479 for el in self.base_iter.by_ref() {
480 if let Some(result) = (self.f)(el) {
481 return Some(result);
482 }
483 }
484 return None;
485 }
486}
487
488impl<I, F, T> FusedIterator for CondenseIter<I, F, T>
489where
490 I: FusedIterator,
491 F: FnMut(I::Item) -> Option<T>,
492{
493}
494
495pub fn condense<I, F, T>(iter: I, f: F) -> CondenseIter<I, F, T>
524where
525 I: Iterator,
526 F: FnMut(I::Item) -> Option<T>,
527{
528 CondenseIter { base_iter: iter, f }
529}
530
531#[test]
532fn test_converted_combinations() {
533 let a = [2, 3, 5, 7];
534 assert_eq!(1, combinations(a.iter(), 0, |_| 0).count());
535 assert_eq!(4, combinations(a.iter(), 1, |_| 0).count());
536 assert_eq!(6, combinations(a.iter(), 2, |_| 0).count());
537 assert_eq!(1, combinations(a.iter(), 4, |_| 0).count());
538 assert_eq!(0, combinations(a.iter(), 5, |_| 0).count());
539}
540
541#[test]
542fn test_powerset() {
543 let a = [1, 2, 3, 4];
544 assert_eq!(16, basic_powerset(a.iter()).count());
545
546 let a = [2, 3];
547 assert_eq!(
548 vec![
549 vec![].into_boxed_slice(),
550 vec![2].into_boxed_slice(),
551 vec![3].into_boxed_slice(),
552 vec![2, 3].into_boxed_slice()
553 ],
554 basic_powerset(a.iter().copied()).collect::<Vec<_>>()
555 );
556
557 let a = [1, 2, 3];
558 assert_eq!(
559 vec![
560 vec![].into_boxed_slice(),
561 vec![1].into_boxed_slice(),
562 vec![2].into_boxed_slice(),
563 vec![3].into_boxed_slice(),
564 vec![1, 2].into_boxed_slice(),
565 vec![1, 3].into_boxed_slice(),
566 vec![2, 3].into_boxed_slice(),
567 vec![1, 2, 3].into_boxed_slice()
568 ],
569 basic_powerset(a.iter().copied()).collect::<Vec<_>>()
570 );
571}
572
573#[allow(deprecated)]
574#[test]
575fn test_multi_cartesian_product() {
576 let a = [0, 1];
577 let b = [0, 1];
578 let c = [-1, 1];
579 let all = [a, b, c];
580 let it = multi_cartesian_product(
581 all.iter().map(|l| l.iter().map(|x| *x)),
582 |x| [x[0], x[1], x[2]],
583 |_, x| *x,
584 );
585 let expected = vec![
586 [0, 0, -1],
587 [0, 0, 1],
588 [0, 1, -1],
589 [0, 1, 1],
590 [1, 0, -1],
591 [1, 0, 1],
592 [1, 1, -1],
593 [1, 1, 1],
594 ];
595 assert_eq!(expected, it.collect::<Vec<_>>());
596}
597
598#[allow(trivial_casts)]
599#[test]
600fn test_multiset_combinations() {
601 let a = [1, 2, 3, 1];
602 let mut iter = multiset_combinations(&a, 3, clone_slice);
603 assert_eq!(&[1, 2, 0, 0][..], &*iter.next().unwrap());
604 assert_eq!(&[1, 1, 1, 0][..], &*iter.next().unwrap());
605 assert_eq!(&[1, 1, 0, 1][..], &*iter.next().unwrap());
606 assert_eq!(&[1, 0, 2, 0][..], &*iter.next().unwrap());
607 assert_eq!(&[1, 0, 1, 1][..], &*iter.next().unwrap());
608
609 assert_eq!(&[0, 2, 1, 0][..], &*iter.next().unwrap());
610 assert_eq!(&[0, 2, 0, 1][..], &*iter.next().unwrap());
611 assert_eq!(&[0, 1, 2, 0][..], &*iter.next().unwrap());
612 assert_eq!(&[0, 1, 1, 1][..], &*iter.next().unwrap());
613
614 assert_eq!(&[0, 0, 3, 0][..], &*iter.next().unwrap());
615 assert_eq!(&[0, 0, 2, 1][..], &*iter.next().unwrap());
616 assert_eq!(None, iter.next());
617
618 assert_eq!(
619 &([] as [[usize; 1]; 0]),
620 &multiset_combinations(&[0], 1, clone_array::<usize, 1>).collect::<Vec<_>>()[..]
621 );
622 assert_eq!(
623 &([[0]] as [[usize; 1]; 1]),
624 &multiset_combinations(&[0], 0, clone_array::<usize, 1>).collect::<Vec<_>>()[..]
625 );
626
627 let a = [0, 2, 0, 1];
628 let mut iter = multiset_combinations(&a, 2, clone_slice);
629 assert_eq!(&[0, 2, 0, 0][..], &*iter.next().unwrap());
630 assert_eq!(&[0, 1, 0, 1][..], &*iter.next().unwrap());
631 assert_eq!(None, iter.next());
632
633 let a = [0, 3, 0, 0, 2, 0];
634 let mut iter = multiset_combinations(&a, 3, clone_slice);
635 assert_eq!(&[0, 3, 0, 0, 0, 0][..], &*iter.next().unwrap());
636 assert_eq!(&[0, 2, 0, 0, 1, 0][..], &*iter.next().unwrap());
637 assert_eq!(&[0, 1, 0, 0, 2, 0][..], &*iter.next().unwrap());
638 assert_eq!(None, iter.next());
639
640 let a = [0, 3, 0, 0, 2, 2, 0];
641 let mut iter = multiset_combinations(&a, 3, clone_slice);
642 assert_eq!(&[0, 3, 0, 0, 0, 0, 0][..], &*iter.next().unwrap());
643 assert_eq!(&[0, 2, 0, 0, 1, 0, 0][..], &*iter.next().unwrap());
644 assert_eq!(&[0, 2, 0, 0, 0, 1, 0][..], &*iter.next().unwrap());
645 assert_eq!(&[0, 1, 0, 0, 2, 0, 0][..], &*iter.next().unwrap());
646 assert_eq!(&[0, 1, 0, 0, 1, 1, 0][..], &*iter.next().unwrap());
647 assert_eq!(&[0, 1, 0, 0, 0, 2, 0][..], &*iter.next().unwrap());
648 assert_eq!(&[0, 0, 0, 0, 2, 1, 0][..], &*iter.next().unwrap());
649 assert_eq!(&[0, 0, 0, 0, 1, 2, 0][..], &*iter.next().unwrap());
650 assert_eq!(None, iter.next());
651
652 let a = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0];
653 let mut iter = multiset_combinations(&a, 10, clone_slice);
654 assert_eq!(
655 &[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0][..],
656 &*iter.next().unwrap()
657 );
658 assert_eq!(1000, iter.count());
659}
660
661#[test]
662fn test_multiset_combinations_k_unlimited() {
663 fn fac(n: usize) -> usize { if n == 0 { 1 } else { n * fac(n - 1) } }
664 let a = [10, 10, 10, 10, 10, 10];
665 assert_eq!(1, multiset_combinations(&a[..], 0, |_| ()).count());
666 assert_eq!(6, multiset_combinations(&a[..], 1, |_| ()).count());
667 assert_eq!(
668 fac(6 + 8 - 1) / fac(6 - 1) / fac(8),
669 multiset_combinations(&a[..], 8, |_| ()).count()
670 );
671}