1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use super::Combinations;
use std::iter::Iterator;
#[derive(Clone, Debug)]
struct FullPermutations<T, const N: usize> {
a: [T; N],
c: [usize; N],
i: usize,
first: bool,
}
impl<T, const N: usize> FullPermutations<T, N> {
fn new(a: [T; N]) -> Self {
Self {
a,
c: [0; N],
i: 0,
first: true,
}
}
}
impl<T, const N: usize> Iterator for FullPermutations<T, N>
where
T: Clone,
{
type Item = [T; N];
fn next(&mut self) -> Option<Self::Item> {
if self.first {
self.first = false;
Some(self.a.clone())
} else {
while self.i < N {
if self.c[self.i] < self.i {
let swap_i = if self.i & 1 == 0 { 0 } else { self.c[self.i] };
self.a.swap(swap_i, self.i);
self.c[self.i] += 1;
self.i = 0;
return Some(self.a.clone());
} else {
self.c[self.i] = 0;
self.i += 1;
}
}
None
}
}
}
#[derive(Clone, Debug)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Permutations<I, const K: usize>
where
I: Iterator,
I::Item: Clone,
{
iter: Combinations<I, K>,
perm_iter: Option<FullPermutations<I::Item, K>>,
}
impl<I, const K: usize> Iterator for Permutations<I, K>
where
I: Iterator,
I::Item: Clone,
{
type Item = [I::Item; K];
fn next(&mut self) -> Option<Self::Item> {
if let Some(perm_iter) = &mut self.perm_iter {
if let Some(a) = perm_iter.next() {
return Some(a);
}
}
self.perm_iter = self.iter.next().map(FullPermutations::new);
self.perm_iter.as_mut().and_then(|i| i.next())
}
}
impl<I, const K: usize> Permutations<I, K>
where
I: Iterator,
I::Item: Clone,
{
pub(crate) fn new(iter: I) -> Self {
let mut iter = Combinations::new(iter);
let perm_iter = iter.next().map(FullPermutations::new);
Self { iter, perm_iter }
}
}
#[cfg(test)]
mod test {
use crate::IterExt;
#[test]
fn none_on_size_too_big() {
let mut permutations = (1..2).permutations::<2>();
assert_eq!(permutations.next(), None);
}
#[test]
fn empty_arr_on_n_zero() {
let mut permutations = (1..5).permutations();
assert_eq!(permutations.next(), Some([]));
assert_eq!(permutations.next(), None);
}
}