組み合わせのイテレーター - 階乗 \(n!\)
For each \(\{ x_i : 0 \leq i \lt n, 0 \leq x_i \lt n, x_i \ne x_j \}\)
/// Number - Iterator - Factorial Permutation (n!)
pub struct Permutation {
n: usize,
idx: usize,
done: bool,
}
impl Permutation {
pub fn new(n: usize) -> Permutation {
Permutation {
n,
idx: 0,
done: false,
}
}
pub fn from(mut perm: Vec<usize>) -> Permutation {
let n = perm.len();
let mut idx = 0;
let mut fact: usize = (1..n).product();
for i in 0..n {
if i > 0 {
fact /= n - i;
}
idx += perm[i] * fact;
for j in i + 1..n {
if perm[j] > perm[i] {
perm[j] -= 1;
}
}
}
Permutation {
n,
idx,
done: false,
}
}
pub fn to_vec(&mut self) -> Option<Vec<usize>> {
if self.done {
return None;
}
if self.n == 0 {
self.done = true;
return Some(vec![]);
}
let mut r = vec![0; self.n];
let mut idx = self.idx;
for k in 1..self.n {
r[k] = idx % (k + 1);
idx /= k + 1;
}
if idx > 0 {
self.done = true;
return None;
}
r.reverse();
let mut b = vec![true; self.n];
b[r[0]] = false;
for k in 1..self.n {
let mut count = 0;
for j in 0..self.n {
if b[j] {
if count == r[k] {
r[k] = j;
b[j] = false;
break;
}
count += 1;
}
}
}
Some(r)
}
}
impl Iterator for Permutation {
type Item = Vec<usize>;
fn next(&mut self) -> Option<Vec<usize>> {
let r = self.to_vec();
self.idx += 1;
r
}
}
#[cfg(test)]
mod test_perm {
use crate::num::iter::perm::*;
#[test]
fn it_works() {
let mut perm = Permutation::new(3);
assert_eq!(perm.next(), Some(vec![0, 1, 2]));
assert_eq!(perm.next(), Some(vec![0, 2, 1]));
assert_eq!(perm.next(), Some(vec![1, 0, 2]));
assert_eq!(perm.next(), Some(vec![1, 2, 0]));
assert_eq!(perm.next(), Some(vec![2, 0, 1]));
assert_eq!(perm.next(), Some(vec![2, 1, 0]));
assert_eq!(perm.next(), None);
}
#[test]
fn perm_of_one() {
let mut perm = Permutation::new(1);
assert_eq!(perm.next(), Some(vec![0]));
assert_eq!(perm.next(), None);
}
#[test]
fn perm_of_zero() {
let mut perm = Permutation::new(0);
assert_eq!(perm.next(), Some(vec![]));
assert_eq!(perm.next(), None);
}
}