ospf_rust_math/combinatorics/
permutations.rs

1use ospf_rust_base::GeneratorIterator;
2
3pub fn permute<T>(input: &[T]) -> Vec<Vec<&T>> {
4    let mut a = input.iter().map(|x| x).collect::<Vec<_>>();
5    let mut p = input.iter().map(|x| 0).collect::<Vec<_>>();
6
7    let mut perms = Vec::new();
8    perms.push(a.clone());
9
10    let mut i = 1;
11    while i < input.len() {
12        if p[i] < i {
13            let j = i % 2 + p[i];
14            a.swap(i, j);
15            perms.push(a.clone());
16            p[i] += 1;
17            i = 1;
18        } else {
19            p[i] = 0;
20            i += 1;
21        }
22    }
23
24    perms
25}
26
27pub fn permute_async<T>(input: &[T]) -> impl Iterator<Item = Vec<&T>> {
28    GeneratorIterator(
29        #[coroutine]
30        || {
31            let mut a = input.iter().map(|x| x).collect::<Vec<_>>();
32            let mut p = input.iter().map(|_| 0).collect::<Vec<_>>();
33
34            let mut i = 1;
35            while i < input.len() {
36                if p[i] < i {
37                    let j = i % 2 + p[i];
38                    a.swap(i, j);
39                    yield a.clone();
40                    p[i] += 1;
41                    i = 1;
42                } else {
43                    p[i] = 0;
44                    i += 1;
45                }
46            }
47        },
48    )
49}