pub trait StreamingIterator<A>
where
A: ?Sized,
{
fn next(&mut self) -> Option<&A>;
fn count(mut self) -> usize
where
Self: Sized,
{
let mut count = 0;
while let Some(_) = self.next() {
count += 1;
}
count
}
}
#[derive(Clone, Debug)]
pub struct Subsets {
n: usize,
data: Vec<usize>,
untouched: bool,
}
impl Subsets {
pub fn new(n: usize) -> Self {
Self {
n,
data: Vec::with_capacity(n),
untouched: true,
}
}
}
impl StreamingIterator<[usize]> for Subsets {
fn next(&mut self) -> Option<&[usize]> {
if self.untouched {
self.untouched = false;
} else {
let mut k = self.n;
loop {
if k == 0 {
return None;
}
k -= 1;
if self.data.last() != Some(&k) {
break;
}
let _ = self.data.pop();
}
self.data.push(k);
}
Some(&self.data)
}
}
#[derive(Clone, Debug)]
pub struct Functions {
n: usize,
k: usize,
data: Vec<usize>,
untouched: bool,
}
impl Functions {
pub fn new(n: usize, k: usize) -> Self {
Self {
n,
k,
data: vec![0; n],
untouched: true,
}
}
}
impl StreamingIterator<[usize]> for Functions {
fn next(&mut self) -> Option<&[usize]> {
if self.untouched {
self.untouched = false;
} else {
let mut i = 0;
while i < self.n && self.data[i] == self.k - 1 {
i += 1;
}
if i == self.n {
return None;
} else {
self.data[i] += 1;
for j in 0..i {
self.data[j] = 0;
}
}
}
Some(&self.data)
}
}
#[derive(Clone, Debug)]
pub struct Choose {
n: usize, k: usize, fixed: usize, data: Vec<usize>,
untouched: bool,
}
impl Choose {
pub fn new(n: usize, k: usize) -> Self {
Self::with_fixed_part(n, k, 0)
}
pub fn with_fixed_part(n: usize, k: usize, fixed: usize) -> Self {
assert!(fixed <= k && k <= n);
Self {
n,
k,
fixed,
data: (0..k).collect(),
untouched: true,
}
}
}
impl StreamingIterator<[usize]> for Choose {
fn next(&mut self) -> Option<&[usize]> {
if self.untouched {
self.untouched = false;
} else {
let mut i = self.k;
loop {
if i <= self.fixed {
return None;
} else {
i -= 1
};
if self.data[i] != self.n - self.k + i {
break;
}
}
self.data[i] += 1;
for j in (i + 1)..self.k {
self.data[j] = self.data[i] + j - i;
}
}
Some(&self.data)
}
}
#[derive(Clone, Debug)]
pub struct Split {
choose: Choose,
second_part: Vec<usize>,
}
impl Split {
#[allow(unused)]
pub fn new(n: usize, k: usize) -> Self {
Self::with_fixed_part(n, k, 0)
}
pub fn with_fixed_part(n: usize, k: usize, fixed: usize) -> Self {
let second_part_size = n - k + fixed;
Self {
choose: Choose::with_fixed_part(n, k, fixed),
second_part: (0..second_part_size).collect(),
}
}
pub fn next(&mut self) -> Option<(&[usize], &[usize])> {
let fixed = self.choose.fixed;
let k = self.choose.k;
let n = self.choose.n;
match self.choose.next() {
Some(p) => {
let mut j = fixed;
for i in fixed..=k {
let start = if i == fixed { fixed } else { p[i - 1] + 1 };
let end = if i == k { n } else { p[i] };
for v in start..end {
self.second_part[j] = v;
j += 1;
}
}
Some((p, &self.second_part))
}
None => None,
}
}
}
#[derive(Clone, Debug)]
pub struct Injection {
n: usize,
k: usize,
data: Vec<usize>,
index: Vec<usize>,
fixed: usize, untouched: bool,
}
impl Injection {
pub fn with_fixed_part(n: usize, k: usize, fixed: usize) -> Self {
assert!(k <= n);
assert!(fixed <= k);
Self {
n,
k,
data: (0..n).collect(),
index: (0..k).collect(),
fixed,
untouched: true,
}
}
pub fn new(n: usize, k: usize) -> Self {
Self::with_fixed_part(n, k, 0)
}
pub fn permutation(n: usize) -> Self {
Self::new(n, n)
}
#[inline]
fn set_index(&mut self, i: usize, val: usize) {
let old_val = self.index[i];
self.index[i] = val;
self.data.swap(i, old_val);
self.data.swap(i, val);
}
}
impl StreamingIterator<[usize]> for Injection {
fn next(&mut self) -> Option<&[usize]> {
if self.untouched {
self.untouched = false;
} else {
if self.k == self.fixed {
return None;
}; let mut i = self.k - 1;
while self.index[i] == self.n - 1 {
if i == self.fixed {
return None;
};
i -= 1
}
let vi = self.index[i] + 1;
self.set_index(i, vi);
for j in (i + 1)..self.k {
self.set_index(j, j);
}
}
Some(&self.data[0..self.k])
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unit_subsets() {
assert_eq!(1, Subsets::new(0).count());
assert_eq!(2, Subsets::new(1).count());
assert_eq!(16, Subsets::new(4).count());
}
#[test]
fn unit_choose() {
assert_eq!(120, Choose::new(10, 3).count());
assert_eq!(3, Choose::new(3, 1).count());
assert_eq!(1, Choose::new(0, 0).count());
assert_eq!(1, Choose::new(2, 2).count());
assert_eq!(120, Choose::with_fixed_part(11, 4, 1).count());
assert_eq!(1, Choose::with_fixed_part(5, 5, 4).count());
assert_eq!(1, Choose::with_fixed_part(4, 4, 4).count());
assert_eq!(1, Choose::with_fixed_part(6, 2, 2).count());
assert_eq!(1, Choose::with_fixed_part(0, 0, 0).count());
}
#[test]
fn unit_split() {
let mut iter = Split::with_fixed_part(12, 5, 2);
let mut count = 0;
while let Some((_a, _b)) = iter.next() {
count += 1;
}
assert_eq!(120, count);
}
#[test]
fn unit_injection() {
assert_eq!(60, Injection::new(5, 3).count());
assert_eq!(1, Injection::new(42, 0).count());
assert_eq!(720, Injection::permutation(6).count());
assert_eq!(20, Injection::with_fixed_part(8, 5, 3).count());
assert_eq!(1, Injection::with_fixed_part(6, 2, 2).count());
assert_eq!(1, Injection::new(0, 0).count());
}
}