extern crate num;
use num::{PrimInt, Unsigned};
use std::cell::RefCell;
use std::collections::{VecDeque};
use std::iter::{ExactSizeIterator, Product, Iterator};
use std::rc::Rc;
use std::sync::{Arc, RwLock};
pub mod copy;
pub fn get_cartesian_size(size: usize, degree: usize) -> usize {
size.pow(degree as u32)
}
pub fn get_cartesian_for<T>(objects: &[T], degree: usize, i: usize) -> Result<Vec<&T>, &str> {
if i >= get_cartesian_size(objects.len(), degree) {
return Err("Parameter `i` is out of bound")
}
if objects.len() < degree {
return Err("Parameter `degree` cannot be larger than size of objects")
}
let w_len = objects.len();
let mut result = VecDeque::new();
let mut idx = i;
(0..degree).for_each(|_| {
let x = idx % w_len;
result.push_front(&objects[x]);
idx /= w_len;
});
return Ok(Vec::from(result))
}
pub fn get_permutation_size(size: usize, degree: usize) -> usize {
divide_factorial(size, size - degree)
}
pub fn get_permutation_for<T>(objects: &[T], degree: usize, x: usize) -> Result<Vec<&T>, &str> {
let mut next_x = x;
let mut states = Vec::<usize>::with_capacity(degree);
let mut slots = vec!(0; degree);
let mut result = Vec::new();
if objects.len() < degree {
return Err("Insufficient number of object in parameters objects for given parameter degree")
}
if x >= divide_factorial(objects.len(), objects.len() - degree) {
return Err("parameter x is outside a possible length");
}
for i in 1..degree + 1 {
let div = divide_factorial(objects.len() - i, objects.len() - degree);
let mut idx = next_x / div;
next_x = next_x % div;
if i > 1 {
let mut counter = idx;
for (j, slot) in slots.iter().enumerate() {
if counter < *slot {
idx += j; result.push(&objects[idx]);
break;
} else {
counter -= slot; }
}
if result.len() < i {
idx = idx + i - 1; result.push(&objects[idx]);
}
let mut insert_point = None;
for j in 0..states.len() {
if idx < states[j] { insert_point = Some(j);
break;
}
}
if let Some(j) = insert_point {
states.insert(j, idx);
} else {
states.push(idx); }
slots[0] = states[0];
for j in 1..slots.len() { if j < states.len() { slots[j] = states[j] - states[j - 1] - 1;
} else { break;
}
}
} else {
result.push(&objects[idx]);
states.push(idx);
slots[0] = idx - 0;
}
}
Ok(result)
}
#[inline(always)]
fn _cartesian_product_core(
n : usize,
set_len : impl Fn(usize) -> usize,
mut assign_res : impl FnMut(usize, usize),
mut cb : impl FnMut() )
{
assert!(n > 0, "Cannot create cartesian product with number of domain == 0");
let mut more = true;
let mut i = 0;
let mut c = vec![0; n];
let n = n - 1;
while more {
assign_res(i, c[i]);
if i == n {
c[i] += 1;
cb();
}
if i < n {
i += 1;
}
while c[i] == set_len(i) { c[i] = 0;
if i == 0 {
more = false;
break;
}
i -= 1;
c[i] += 1;
}
}
}
pub fn cartesian_product<'a, T, F>(
sets : &'a [&[T]],
mut cb : F)
where T : 'a,
for<'r> F : FnMut(&'r [&'a T]) + 'a
{
let mut result = vec![&sets[0][0]; sets.len()];
let copied = result.as_slice() as *const [&T];
unsafe {
_cartesian_product_core(
sets.len(),
#[inline(always)] |i| {
sets[i].len()
},
#[inline(always)] |i, c| {
result[i] = &sets[i][c];
},
#[inline(always)] || {
cb(&*copied);
});
}
}
pub unsafe fn unsafe_cartesian_product<'a, T>(sets : &'a[&[T]], result : *mut [&'a T], cb : impl FnMut()) {
_cartesian_product_core(
sets.len(),
#[inline(always)] |i| {
sets[i].len()
},
#[inline(always)] |i, c| {
(*result)[i] = &sets[i][c];
}, cb);
}
pub fn cartesian_product_cell<'a, T>(sets : &'a[&[T]], result : Rc<RefCell<&'a mut [&'a T]>>, cb : impl FnMut()) {
_cartesian_product_core(
sets.len(),
#[inline(always)] |i| {
sets[i].len()
},
#[inline(always)] |i, c| {
result.borrow_mut()[i] = &sets[i][c];
}, cb);
}
pub fn cartesian_product_sync<'a, T>(sets : &'a[&[T]], result : Arc<RwLock<Vec<&'a T>>>, cb : impl FnMut()) {
_cartesian_product_core(
sets.len(),
#[inline(always)] |i| {
sets[i].len()
},
#[inline(always)] |i, c| {
result.write().unwrap()[i] = &sets[i][c];
}, cb);
}
pub fn self_cartesian_product<'a, T, F>(set : &'a [T], n : usize, mut cb : F)
where T : 'a,
for<'r> F : FnMut(&'r [&'a T]) + 'a
{
let mut result = vec![&set[0]; n];
let copied = result.as_slice() as *const [&T];
unsafe {
_cartesian_product_core(
n,
#[inline(always)] |_| {
set.len()
},
#[inline(always)] |i, c| {
result[i] = &set[c];
},
#[inline(always)] || {
cb(&*copied);
});
}
}
pub unsafe fn unsafe_self_cartesian_product<'a, T>(set : &'a[T], n : usize, result : *mut [&'a T], cb : impl FnMut()) {
_cartesian_product_core(
n,
#[inline(always)] |_| {
set.len()
},
#[inline(always)] |i, c| {
(*result)[i] = &set[c];
}, cb);
}
pub fn self_cartesian_product_cell<'a, T>(set : &'a[T], n : usize, result : Rc<RefCell<&'a mut [&'a T]>>, cb : impl FnMut()) {
_cartesian_product_core(
n,
#[inline(always)] |_| {
set.len()
},
#[inline(always)] |i, c| {
result.borrow_mut()[i] = &set[c];
}, cb);
}
pub fn self_cartesian_product_sync<'a, T>(set : &'a[T], n : usize, result : Arc<RwLock<Vec<&'a T>>>, cb : impl FnMut()) {
_cartesian_product_core(
n,
#[inline(always)] |_| {
set.len()
},
#[inline(always)] |i, c| {
result.write().unwrap()[i] = &set[c];
}, cb);
}
pub fn combination<T>(domain: &[T], r : usize, mut cb : impl FnMut(&[&T]) -> ()) {
let (mut combination, mut map) = create_k_set(domain, r);
cb(&combination);
while let Some(_) = swap_k((&mut combination, &mut map), domain) {
cb(&combination);
}
}
pub unsafe fn unsafe_combination<'a, T>(domain: &'a[T], r : usize, result : *mut [&'a T], mut cb : impl FnMut() -> ()) {
let mut mask = 0u128;
unsafe_create_k_set(domain, r, result, &mut mask);
cb();
while let Some(_) = swap_k((&mut *result, &mut mask), domain) {
cb();
}
}
pub fn combination_cell<'a, T>(domain: &'a[T], r : usize, result : Rc<RefCell<&'a mut [&'a T]>>, mut cb : impl FnMut() -> ()) {
let mut mask = 0u128;
create_k_set_in_cell(domain, r, &result, &mut mask);
cb();
while let Some(_) = swap_k_in_cell((&result, &mut mask), domain) {
cb();
}
}
pub fn combination_sync<'a, T>(domain: &'a[T], r : usize, result : Arc<RwLock<Vec<&'a T>>>, mut cb : impl FnMut() -> ()) {
let mut mask = 0u128;
create_k_set_sync(domain, r, &result, &mut mask);
cb();
while let Some(_) = swap_k_sync((&result, &mut mask), domain) {
cb();
}
}
fn _core_large_combination<'a, T : 'a, R : 'a>(
domain : &'a [T],
r : usize,
first_result_fn : impl FnOnce(&mut Vec<usize>, &'a [T], usize) -> R,
mut next_result_fn : impl FnMut(usize, usize, &mut R),
mut cb : impl FnMut(&R))
{
#[inline(always)]
fn move_cur_res<'a, T, R>(c : &mut [usize], domain : &'a [T], result : &mut R, next_result_fn : &mut FnMut(usize, usize, &mut R)) {
let n = c.len();
let max = domain.len();
let mut i = c.len() - 1;
if c[i] < max - n + i {
c[i] += 1;
next_result_fn(i, c[i], result);
} else {
while c[i] >= max - n + i {
i -= 1;
}
c[i] += 1;
next_result_fn(i, c[i], result);
i += 1;
(i..c.len()).for_each(|i| {
c[i] = c[i - 1] + 1;
next_result_fn(i, c[i], result);
});
}
}
assert_ne!(r, 0, "The combination size cannot be 0");
assert!(domain.len() >= r, "The combination size cannot be larger than size of data");
let mut c : Vec<usize> = Vec::new();
let mut result = first_result_fn(&mut c, domain, r);
cb(&result);
let n = r - 1;
c[n] += 1;
if c[n] < domain.len() {
next_result_fn(n, c[n], &mut result);
cb(&result);
} else {
return;
}
while c[0] < domain.len() - r {
move_cur_res(&mut c, domain, &mut result, &mut next_result_fn);
cb(&result);
}
}
pub fn large_combination<'a, T, F>(domain: &'a [T], r : usize, mut cb : F)
where T : 'a,
for<'r> F : FnMut(&'r[&'a T]) + 'a
{
let mut result : Vec<&T> = Vec::with_capacity(r);
_core_large_combination(domain,
r,
#[inline(always)]
|c, domain, r| {
(0..r).for_each(|i| {
result.push(&domain[i]);
c.push(i);
});
result
},
#[inline(always)]
|i, j, result| {
result[i] = &domain[j];
},
#[inline(always)]
|result| {
cb(result);
}
);
}
pub unsafe fn unsafe_large_combination<'a, T : 'a>(domain: &'a [T], r : usize, result : *mut [&'a T], mut cb : impl FnMut()) {
_core_large_combination(domain,
r,
#[inline(always)]
|c, domain, r| {
let result = &mut *result;
(0..r).for_each(|i| {
result[i] = &domain[i];
c.push(i);
});
result
},
#[inline(always)]
|i, j, result| {
result[i] = &domain[j];
},
#[inline(always)]
|_| {
cb();
}
);
}
pub fn large_combination_cell<'a, T : 'a>(domain: &'a[T], r : usize, result : Rc<RefCell<&'a mut [&'a T]>>, mut cb : impl FnMut() -> ()) {
_core_large_combination(domain,
r,
#[inline(always)]
|c, domain, r| {
(0..r).for_each(|i| {
result.borrow_mut()[i] = &domain[i];
c.push(i);
});
result
},
#[inline(always)]
|i, j, result| {
result.borrow_mut()[i] = &domain[j];
},
#[inline(always)]
|_| {
cb();
}
);
}
pub fn large_combination_sync<'a, T : 'a>(domain: &'a[T], r : usize, result : Arc<RwLock<Vec<&'a T>>>, mut cb : impl FnMut() -> ()) {
_core_large_combination(domain,
r,
#[inline(always)]
|c, domain, r| {
{
let mut writer = result.write().unwrap();
(0..r).for_each(|i| {
writer[i] = &domain[i];
c.push(i);
});
}
result
},
#[inline(always)]
|i, j, result| {
result.write().unwrap()[i] = &domain[j];
},
#[inline(always)]
|_| {
cb();
}
);
}
fn _heap_permutation_core(n : usize, mut swap : impl FnMut(usize, usize), mut cb : impl FnMut()) {
let mut c = vec![0; n];
let mut i = 0;
while i < n {
if c[i] < i {
if i & 1 == 0 { swap(0, i);
} else {
swap(c[i], i);
}
cb();
c[i] += 1;
i = 0;
} else {
c[i] = 0;
i += 1;
}
}
}
pub fn heap_permutation<'a, T>(d : &'a mut [T], mut cb : impl FnMut(&[T]) -> () + 'a) {
let copied = d as *const [T];
unsafe {
_heap_permutation_core(
d.len(),
#[inline(always)] |from, to| {
d.swap(from, to);
},
#[inline(always)] || {
cb(&*copied)
});
}
}
pub fn heap_permutation_cell<T>(d : &Rc<RefCell<&mut [T]>>, cb : impl FnMut() -> ()) {
let n = d.borrow().len();
_heap_permutation_core(
n,
#[inline(always)] |from, to| {
d.borrow_mut().swap(from, to);
},
cb
);
}
pub fn heap_permutation_sync<T>(d : &Arc<RwLock<Vec<T>>>, cb : impl FnMut() -> ()) {
let n = d.read().unwrap().len();
_heap_permutation_core(
n,
#[inline(always)] |from, to| {
d.write().unwrap().swap(from, to);
},
cb
);
}
#[allow(unused)]
macro_rules! _k_permutation_core {
($k : expr, $n : expr, $swap_fn : expr, $permute_fn : expr, $cb : expr) => {
if $n < $k {
panic!("Cannot create k-permutation of size {} for data of length {}", $k, $n);
} else if $k == 0 {
return
}
$cb;
$permute_fn;
while let Some(_) = $swap_fn { $cb;
$permute_fn; }
};
}
pub fn k_permutation<'a, T, F>(d : &'a [T], k : usize, mut cb : F)
where T : 'a,
for<'r> F : FnMut(&'r [&'a T]) + 'a
{
assert_ne!(k, 0);
assert!(k <= d.len());
large_combination(d, k, move |result| {
cb(result);
heap_permutation(&mut result.to_owned(), |r| cb(r));
});
}
pub unsafe fn unsafe_k_permutation<'a, T>(d : &'a [T], k : usize, result : *mut [&'a T], mut cb : impl FnMut() -> ()) {
assert_eq!(k, (*result).len());
unsafe_large_combination(d, k, result, || {
cb();
let buffer = (*result).to_owned();
heap_permutation(&mut *result, |_| {
cb();
});
buffer.iter().enumerate().for_each(|(i, t)| (*result)[i] = *t)
});
}
pub fn k_permutation_cell<'a, T>(d : &'a [T], k : usize, result : Rc<RefCell<&'a mut [&'a T]>>, mut cb : impl FnMut() -> ()) {
assert_ne!(k, 0);
assert_eq!(k, result.borrow().len());
large_combination_cell(d, k, Rc::clone(&result), || {
cb();
let origin = (*result).borrow().to_owned();
heap_permutation_cell(&result, || {
cb();
});
origin.iter().enumerate().for_each(|(i, t)| result.borrow_mut()[i] = *t)
});
}
pub fn k_permutation_sync<'a, T>(d : &'a [T], k : usize, result : Arc<RwLock<Vec<&'a T>>>, mut cb : impl FnMut() -> ()) {
assert_ne!(k, 0);
assert_eq!(k, result.read().unwrap().len());
large_combination_sync(d, k, Arc::clone(&result), || {
cb();
let origin = (*result).read().unwrap().to_owned();
heap_permutation_sync(&result, || {
cb();
});
origin.iter().enumerate().for_each(|(i, t)| result.write().unwrap()[i] = *t)
});
}
pub trait IteratorReset {
fn reset(&mut self);
}
#[inline(always)]
fn _cartesian_next_core<'a>(
i : &mut usize,
c : &mut Vec<usize>,
exhausted : &mut bool,
n : usize,
domain_len : impl Fn(usize) -> usize,
mut into_result : impl FnMut(usize, usize) + 'a)
{
while *i < n && ! *exhausted {
if c[*i] == domain_len(*i) {
let mut k = *i;
while c[k] == domain_len(k) && k > 0 {
c[k] = 1;
into_result(k, 0);
k -= 1;
}
if k == 0 && c[k] == domain_len(k) {
*exhausted = true;
} else {
into_result(k, c[k]);
c[k] += 1;
}
} else {
into_result(*i, c[*i]);
c[*i] += 1;
}
*i += 1;
}
}
pub struct CartesianProductIterator<'a, T> where T : 'a {
c : Vec<usize>,
domains : &'a [&'a [T]],
exhausted : bool,
i : usize,
result : Vec<&'a T>
}
impl<'a, T> CartesianProductIterator<'a, T> where T : 'a {
pub fn new(domains : &'a[&[T]]) -> CartesianProductIterator<'a, T> {
CartesianProductIterator {
c : vec![0; domains.len()],
domains : domains,
exhausted : false,
i : 0,
result : vec![&domains[0][0]; domains.len()]
}
}
pub fn into_iter(self) -> Self {
self
}
}
impl<'a, T> Iterator for CartesianProductIterator<'a, T> {
type Item = Vec<&'a T>;
fn next(&mut self) -> Option<Vec<&'a T>> {
let domains = self.domains;
let result = &mut self.result;
_cartesian_next_core(
&mut self.i,
&mut self.c,
&mut self.exhausted,
domains.len(),
#[inline(always)]
|k| {
domains[k].len()
},
#[inline(always)]
|i, j| {
result[i] = &domains[i][j];
}
);
if self.exhausted {
None
} else {
self.i -= 1; Some(result.to_owned())
}
}
}
impl<'a, T> IteratorReset for CartesianProductIterator<'a, T> {
fn reset(&mut self) {
self.c = vec![0; self.domains.len()];
self.exhausted = false;
self.i = 0;
}
}
impl<'a, T> ExactSizeIterator for CartesianProductIterator<'a, T> {
fn len(&self) -> usize {
self.domains.iter().fold(1, |cum, d| {cum * d.len()})
}
}
pub struct CartesianProductCellIter<'a, T> where T : 'a {
c : Vec<usize>,
domains : &'a [&'a [T]],
exhausted : bool,
i : usize,
result : Rc<RefCell<&'a mut [&'a T]>>
}
impl<'a, T> CartesianProductCellIter<'a, T> {
pub fn new(data : &'a [&'a [T]], result : Rc<RefCell<&'a mut [&'a T]>>) -> CartesianProductCellIter<'a, T> {
CartesianProductCellIter {
c : vec![0; data.len()],
domains : data,
exhausted : false,
i : 0,
result : result
}
}
pub fn into_iter(self) -> Self {
self
}
}
impl<'a, T> Iterator for CartesianProductCellIter<'a, T> where T : 'a {
type Item = ();
fn next(&mut self) -> Option<()> {
let mut result = self.result.borrow_mut();
let domains = self.domains;
_cartesian_next_core(
&mut self.i,
&mut self.c,
&mut self.exhausted,
domains.len(),
#[inline(always)]
|k| {
domains[k].len()
},
#[inline(always)]
|i, j| {
result[i] = &domains[i][j];
}
);
if self.exhausted {
None
} else {
self.i -= 1;
Some(())
}
}
}
impl<'a, T> IteratorReset for CartesianProductCellIter<'a, T> {
fn reset(&mut self) {
self.c.iter_mut().for_each(|c| {*c = 0});
self.exhausted = false;
self.i = 0;
}
}
impl<'a, T> ExactSizeIterator for CartesianProductCellIter<'a, T> {
fn len(&self) -> usize {
self.domains.iter().fold(1, |cum, d| {cum * d.len()})
}
}
pub struct CartesianProductRefIter<'a, T> where T : 'a {
c : Vec<usize>,
domains : &'a [&'a [T]],
exhausted : bool,
i : usize,
result : &'a mut [&'a T]
}
impl<'a, T> CartesianProductRefIter<'a, T> {
pub unsafe fn new(data : &'a [&'a [T]], result : *mut [&'a T]) -> CartesianProductRefIter<'a, T> {
CartesianProductRefIter {
c : vec![0; data.len()],
domains : data,
exhausted : false,
i : 0,
result : &mut *result
}
}
pub fn into_iter(self) -> Self {
self
}
}
impl<'a, T> Iterator for CartesianProductRefIter<'a, T> where T : 'a {
type Item = ();
fn next(&mut self) -> Option<()> {
let result = &mut self.result;
let domains = self.domains;
_cartesian_next_core(
&mut self.i,
&mut self.c,
&mut self.exhausted,
domains.len(),
#[inline(always)]
|k| {
domains[k].len()
},
#[inline(always)]
|i, j| {
result[i] = &domains[i][j];
}
);
if self.exhausted {
None
} else {
self.i -= 1;
Some(())
}
}
}
impl<'a, T> IteratorReset for CartesianProductRefIter<'a, T> {
fn reset(&mut self) {
self.c.iter_mut().for_each(|c| {*c = 0});
self.exhausted = false;
self.i = 0;
}
}
impl<'a, T> ExactSizeIterator for CartesianProductRefIter<'a, T> {
fn len(&self) -> usize {
self.domains.iter().fold(1, |cum, d| {cum * d.len()})
}
}
#[inline(always)]
fn _gosper_next_core(map : &mut u128, mut into_result : impl FnMut(usize, usize)) {
let mut i = 0;
let mut j = 0;
let mut mask = *map;
while mask > 0 {
if mask & 1 == 1 {
into_result(i, j);
i += 1;
}
mask >>= 1;
j += 1;
}
stanford_combination(map);
}
pub struct GosperCombinationIterator<'a, T> where T : 'a {
data : &'a [T], len : usize, r : usize, x : u128, }
impl<'a, T> GosperCombinationIterator<'a, T> {
pub fn new(data : &[T], r : usize) -> GosperCombinationIterator<T> {
let mut x : u128 = 1;
x <<= r;
x -= 1;
let n = data.len();
GosperCombinationIterator {
data : data,
len : divide_factorial(n, multiply_factorial(n - r, r)),
r : r,
x : x
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn reset(&mut self) {
self.x = 1;
self.x <<= self.r;
self.x -= 1;
}
}
impl<'a, T> IntoIterator for GosperCombinationIterator<'a, T> {
type Item = Vec<&'a T>;
type IntoIter = CombinationIterator<'a, T>;
fn into_iter(self) -> CombinationIterator<'a, T> {
CombinationIterator {
data : self.data,
r : self.r,
x : self.x
}
}
}
pub struct CombinationIterator<'a, T> where T : 'a {
data : &'a [T], r : usize, x : u128, }
impl<'a, T> Iterator for CombinationIterator<'a, T> {
type Item = Vec<&'a T>;
fn next(&mut self) -> Option<Vec<&'a T>> {
let mut combination : Vec<&T> = Vec::new();
if 128 - self.x.leading_zeros() as usize > self.data.len() {
return None
}
let data = self.data;
let map = &mut self.x;
_gosper_next_core(map,
#[inline(always)]
|_, j| {
combination.push(&data[j]);
}
);
return Some(combination)
}
}
impl<'a, T> IteratorReset for CombinationIterator<'a, T> {
fn reset(&mut self) {
self.x = 1;
self.x <<= self.r;
self.x -= 1;
}
}
impl<'a, T> ExactSizeIterator for CombinationIterator<'a, T> {
fn len(&self) -> usize {
let n = self.data.len();
divide_factorial(n, multiply_factorial(n - self.r, self.r))
}
}
pub struct GosperCombinationCellIter<'a, T> where T : 'a {
data : &'a [T], len : usize, r : usize, x : u128,
result : Rc<RefCell<&'a mut [&'a T]>>
}
impl<'a, T> GosperCombinationCellIter<'a, T> {
pub fn new(data : &'a [T], r : usize, result : Rc<RefCell<&'a mut [&'a T]>>) -> GosperCombinationCellIter<'a, T> {
let mut x : u128 = 1;
x <<= r;
x -= 1;
let n = data.len();
GosperCombinationCellIter {
data : data,
len : divide_factorial(n, multiply_factorial(n - r, r)),
r : r,
x : x,
result : result
}
}
pub fn len(&self) -> usize {
self.len
}
}
impl<'a, T> IntoIterator for GosperCombinationCellIter<'a, T> {
type Item = ();
type IntoIter = CombinationCellIter<'a, T>;
fn into_iter(self) -> CombinationCellIter<'a, T> {
CombinationCellIter {
data : self.data,
r : self.r,
x : self.x,
result : self.result
}
}
}
pub struct CombinationCellIter<'a, T> where T : 'a {
data : &'a [T], r : usize, x : u128,
result : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T> Iterator for CombinationCellIter<'a, T> {
type Item = ();
fn next(&mut self) -> Option<()> {
if 128 - self.x.leading_zeros() as usize > self.data.len() {
return None
}
let data = self.data;
let map = &mut self.x;
let mut result = self.result.borrow_mut();
_gosper_next_core(map,
#[inline(always)]
|i, j| {
result[i] = &data[j];
}
);
return Some(())
}
}
impl<'a, T> IteratorReset for CombinationCellIter<'a, T> {
fn reset(&mut self) {
self.x = 1;
self.x <<= self.r;
self.x -= 1;
}
}
impl<'a, T> ExactSizeIterator for CombinationCellIter<'a, T> {
fn len(&self) -> usize {
let n = self.data.len();
divide_factorial(n, multiply_factorial(n - self.r, self.r))
}
}
pub struct GosperCombinationRefIter<'a, T> where T : 'a {
data : &'a [T], len : usize, r : usize, x : u128,
result : &'a mut [&'a T]
}
impl<'a, T> GosperCombinationRefIter<'a, T> {
pub unsafe fn new(data : &'a [T], r : usize, result : *mut [&'a T]) -> GosperCombinationRefIter<'a, T> {
let mut x : u128 = 1;
x <<= r;
x -= 1;
let n = data.len();
GosperCombinationRefIter {
data : data,
len : divide_factorial(n, multiply_factorial(n - r, r)),
r : r,
x : x,
result : &mut *result
}
}
pub fn len(&self) -> usize {
self.len
}
}
impl<'a, T> IntoIterator for GosperCombinationRefIter<'a, T> {
type Item = ();
type IntoIter = CombinationRefIter<'a, T>;
fn into_iter(self) -> CombinationRefIter<'a, T> {
CombinationRefIter {
data : self.data,
r : self.r,
x : self.x,
result : self.result
}
}
}
pub struct CombinationRefIter<'a, T> where T : 'a {
data : &'a [T], r : usize, x : u128,
result : &'a mut[&'a T]
}
impl<'a, T> Iterator for CombinationRefIter<'a, T> {
type Item = ();
fn next(&mut self) -> Option<()> {
if 128 - self.x.leading_zeros() as usize > self.data.len() {
return None
}
let data = self.data;
let map = &mut self.x;
let result = &mut self.result;
_gosper_next_core(map,
#[inline(always)]
|i, j| {
result[i] = &data[j];
}
);
return Some(())
}
}
impl<'a, T> IteratorReset for CombinationRefIter<'a, T> {
fn reset(&mut self) {
self.x = 1;
self.x <<= self.r;
self.x -= 1;
}
}
impl<'a, T> ExactSizeIterator for CombinationRefIter<'a, T> {
fn len(&self) -> usize {
let n = self.data.len();
divide_factorial(n, multiply_factorial(n - self.r, self.r))
}
}
#[inline(always)]
fn _large_comb_next_core<'a, T, R, V>(
c : &mut [usize],
data : & [T],
iterated : &mut Option<()>,
r : usize,
result : &mut R,
mut result_change_fn : impl FnMut(usize, usize, &mut R),
result_fn : impl Fn(&R) -> V
) -> Option<V>
where T : 'a,
{
#[inline(always)]
fn move_cur_res<'a, T, R>(
c : &mut [usize],
domain : &'a [T],
result : &mut R,
mut next_result_fn : impl FnMut(usize, usize, &mut R)
) -> Option<()> {
let n = c.len();
let max = domain.len();
let mut i = c.len() - 1;
if c[i] < max - n + i {
c[i] += 1;
next_result_fn(i, c[i], result);
Some(())
} else {
while c[i] >= max - n + i && i > 0 {
i -= 1;
}
if c[0] >= max - n {
return None;
}
c[i] += 1;
next_result_fn(i, c[i], result);
i += 1;
(i..c.len()).for_each(|i| {
c[i] = c[i - 1] + 1;
next_result_fn(i, c[i], result);
});
Some(())
}
}
#[inline(always)]
fn init_once<'a, F, R>(
c : &mut [usize],
r : usize,
result : &mut R,
result_change_fn : &mut F
) -> Option<()>
where for<'r> F : FnMut(usize, usize, &mut R),
{
(0..r).for_each(|i| {
result_change_fn(i, i, result);
c[i] = i;
});
return Some(());
}
if let None = iterated {
*iterated = Some(());
init_once(c, r, result, &mut result_change_fn);
if data.len() == 1 {
c[0] = 1; }
return Some(result_fn(&*result));
}
match move_cur_res(c, data, result, result_change_fn) {
Some(_) => Some(result_fn(&*result)),
None => None
}
}
pub struct LargeCombinationIterator<'a, T> where T : 'a {
c : Vec<usize>, data : &'a [T], i : usize, nexted : Option<()>, len : usize, r : usize, result : Vec<&'a T>, }
impl<'a, T> LargeCombinationIterator<'a, T> {
pub fn new(data : &[T], r : usize) -> LargeCombinationIterator<T> {
assert_ne!(r, 0);
assert!(r <= data.len());
let c = vec![0; r];
let n = data.len();
let result = vec![&data[0]; r];
LargeCombinationIterator {
c,
data : data,
i : 0,
nexted : None,
len : divide_factorial(n, multiply_factorial(n - r, r)),
r : r,
result : result
}
}
pub fn iter(&mut self) -> &mut Self {
self
}
}
impl<'a, T> Iterator for LargeCombinationIterator<'a, T> {
type Item = Vec<&'a T>;
fn next(&mut self) -> Option<Vec<&'a T>> {
let data = &self.data;
_large_comb_next_core(
&mut self.c,
data,
&mut self.nexted,
self.r,
&mut self.result,
|i, j, r| {
r[i] = &data[j];
},
|r| {
r.to_owned()
}
)
}
}
impl<'a, T> IteratorReset for LargeCombinationIterator<'a, T> {
fn reset(&mut self) {
self.nexted = None;
self.c.iter_mut().for_each(|c| *c = 0);
self.i = 0;
}
}
impl<'a, T> ExactSizeIterator for LargeCombinationIterator<'a, T> {
fn len(&self) -> usize {
self.len
}
}
pub struct LargeCombinationCellIter<'a, T> where T : 'a {
c : Vec<usize>, data : &'a [T], i : usize, nexted : Option<()>, len : usize, r : usize,
result : Rc<RefCell<&'a mut [&'a T]>>
}
impl<'a, T> LargeCombinationCellIter<'a, T> {
pub fn new(data : &'a [T], r : usize, result : Rc<RefCell<&'a mut [&'a T]>>) -> LargeCombinationCellIter<'a, T> {
assert_ne!(r, 0);
assert!(r <= data.len());
let c = vec![0; r];
let n = data.len();
LargeCombinationCellIter {
c,
data : data,
i : 0,
nexted : None,
len : divide_factorial(n, multiply_factorial(n - r, r)),
r : r,
result : result
}
}
pub fn iter(&mut self) -> &mut Self {
self
}
}
impl<'a, T> Iterator for LargeCombinationCellIter<'a, T> {
type Item = ();
fn next(&mut self) -> Option<()> {
let data = &self.data;
_large_comb_next_core(
&mut self.c,
data,
&mut self.nexted,
self.r,
&mut self.result,
|i, j, r| {
r.borrow_mut()[i] = &data[j];
},
|_| {
()
}
)
}
}
impl<'a, T> IteratorReset for LargeCombinationCellIter<'a, T> {
fn reset(&mut self) {
self.nexted = None;
self.c.iter_mut().for_each(|c| *c = 0);
self.i = 0;
}
}
impl<'a, T> ExactSizeIterator for LargeCombinationCellIter<'a, T> {
fn len(&self) -> usize {
self.len
}
}
pub struct LargeCombinationRefIter<'a, T> where T : 'a {
c : Vec<usize>, data : &'a [T], i : usize, nexted : Option<()>, len : usize, r : usize,
result : &'a mut [&'a T]
}
impl<'a, T> LargeCombinationRefIter<'a, T> {
pub unsafe fn new(data : &'a [T], r : usize, result : *mut [&'a T]) -> LargeCombinationRefIter<'a, T> {
assert_ne!(r, 0);
assert!(r <= (*data).len());
let c = vec![0; r];
let n = data.len();
LargeCombinationRefIter {
c,
data : data,
i : 0,
nexted : None,
len : divide_factorial(n, multiply_factorial(n - r, r)),
r : r,
result : &mut *result
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn iter(&mut self) -> &mut Self {
self
}
}
impl<'a, T> Iterator for LargeCombinationRefIter<'a, T> {
type Item = ();
fn next(&mut self) -> Option<()> {
let data = &self.data;
_large_comb_next_core(
&mut self.c,
data,
&mut self.nexted,
self.r,
&mut self.result,
|i, j, r| {
r[i] = &data[j];
},
|_| {
()
}
)
}
}
impl<'a, T> IteratorReset for LargeCombinationRefIter<'a, T> {
fn reset(&mut self) {
self.nexted = None;
self.c.iter_mut().for_each(|c| *c = 0);
self.i = 0;
}
}
impl<'a, T> ExactSizeIterator for LargeCombinationRefIter<'a, T> {
fn len(&self) -> usize {
self.len
}
}
#[inline(always)]
fn _heap_next_core(
c : &mut[usize],
i : &mut usize,
n : usize,
mut swap_fn : impl FnMut(usize, usize))
{
while *i < n {
if c[*i] < *i {
if *i % 2 == 0 {
swap_fn(0, *i);
} else {
swap_fn(c[*i], *i);
}
c[*i] += 1;
*i = 0;
return
} else {
c[*i] = 0;
*i += 1;
}
}
}
pub struct HeapPermutationIterator<'a, T> where T : 'a {
c : Box<[usize]>,
data : &'a mut [T],
i : usize
}
impl<'a, T> HeapPermutationIterator<'a, T> {
pub fn new(data : &mut [T]) -> HeapPermutationIterator<T> {
HeapPermutationIterator {
c : vec![0; data.len()].into_boxed_slice(),
data : data,
i : 0
}
}
pub fn into_iter(self) -> Self {
self
}
}
impl<'a, T> Iterator for HeapPermutationIterator<'a, T> where T : Clone {
type Item = Vec<T>;
fn next(&mut self) -> Option<Self::Item> {
let HeapPermutationIterator {ref mut c, ref mut data, ref mut i } = self;
let n = data.len();
let mut result : Option<Vec<T>> = None;
_heap_next_core(c, i, n,
#[inline(always)]
|from, to| {
data.swap(from, to);
result = Some(data.to_owned());
}
);
result
}
}
impl<'a, T> IteratorReset for HeapPermutationIterator<'a, T> {
fn reset(&mut self) {
self.i = 0;
self.c.iter_mut().for_each(|c| {*c = 0;});
}
}
impl<'a, T> ExactSizeIterator for HeapPermutationIterator<'a, T> where T : Clone {
fn len(&self) -> usize {
factorial(self.data.len())
}
}
pub struct HeapPermutationCellIter<'a, T> where T : 'a {
c : Vec<usize>,
data : Rc<RefCell<&'a mut[T]>>,
i : usize
}
impl<'a, T> HeapPermutationCellIter<'a, T> {
pub fn new(data : Rc<RefCell<&'a mut[T]>>) -> HeapPermutationCellIter<'a, T> {
HeapPermutationCellIter {
c : vec![0; data.borrow().len()],
data : Rc::clone(&data),
i : 0
}
}
}
impl<'a, T> Iterator for HeapPermutationCellIter<'a, T> where T : 'a {
type Item= ();
fn next(&mut self) -> Option<()> {
let HeapPermutationCellIter {ref mut c, ref mut data, ref mut i } = self;
let n = data.borrow().len();
let mut result : Option<()> = None;
_heap_next_core(c, i, n,
#[inline(always)]
|from, to| {
data.borrow_mut().swap(from, to);
result = Some(());
}
);
result
}
}
impl<'a, T> IteratorReset for HeapPermutationCellIter<'a, T> {
fn reset(&mut self) {
self.i = 0;
self.c.iter_mut().for_each(|c| {*c = 0;});
}
}
impl<'a, T> ExactSizeIterator for HeapPermutationCellIter<'a, T> {
fn len(&self) -> usize {
factorial(self.data.borrow().len())
}
}
pub struct HeapPermutationRefIter<'a, T> where T : 'a {
c : Vec<usize>,
data : &'a mut [T],
i : usize
}
impl<'a, T> HeapPermutationRefIter<'a, T> {
pub unsafe fn new(data : *mut [T]) -> HeapPermutationRefIter<'a, T> {
HeapPermutationRefIter {
c : vec![0; (*data).len()],
data : &mut *data,
i : 0
}
}
pub fn into_iter(self) -> Self {
self
}
}
impl<'a, T> Iterator for HeapPermutationRefIter<'a, T> {
type Item = ();
fn next(&mut self) -> Option<Self::Item> {
let HeapPermutationRefIter {ref mut c, ref mut data, ref mut i } = self;
let n = data.len();
let mut result : Option<()> = None;
_heap_next_core(c, i, n,
#[inline(always)]
|from, to| {
data.swap(from, to);
result = Some(());
}
);
result
}
}
impl<'a, T> IteratorReset for HeapPermutationRefIter<'a, T> {
fn reset(&mut self) {
self.i = 0;
self.c.iter_mut().for_each(|c| {*c = 0;});
}
}
impl<'a, T> ExactSizeIterator for HeapPermutationRefIter<'a, T> {
fn len(&self) -> usize {
factorial(self.data.len())
}
}
#[inline(always)]
fn _k_permutation_next_core<'a, T, U, V, W, X>(
combinator : T,
permutator : &'a mut Option<U>,
permuted : X,
new_permutator_fn : impl FnOnce(&'a mut Option<U>, X, V) + 'a
) -> Option<()>
where T : Iterator<Item=V> + 'a,
U : Iterator<Item=W> + IteratorReset + 'a,
V : 'a,
X : 'a
{
#[inline(always)]
fn get_next<'a, T, U, V, W, X>(
combinator : T,
permutator : &'a mut Option<U>,
permuted : X,
new_permutator_fn : impl FnOnce(&'a mut Option<U>, X, V)
) -> Option<()>
where T : Iterator<Item=V> + 'a,
U : Iterator<Item=W> + IteratorReset + 'a,
V : 'a,
X : 'a
{
if let Some(ref mut perm) = *permutator {
if let Some(_) = perm.next() {
return Some(());
}
}
if let Ok(_) = next_permutator(combinator, permutator, permuted, new_permutator_fn) {
Some(())
} else {
return None;
}
}
#[inline(always)]
fn next_permutator<'a, T, U, V, W, X>(
mut combinator : T,
permutator : &'a mut Option<U>,
permuted : X,
new_permutator_fn : impl FnOnce(&'a mut Option<U>, X, V)
) -> Result<(), ()>
where T : Iterator<Item = V> + 'a,
U : Iterator<Item=W> + IteratorReset + 'a,
V : 'a,
X : 'a
{
if let Some(v) = combinator.next() {
new_permutator_fn(&mut *permutator, permuted, v);
Ok(())
} else {
Err(())
}
}
get_next(combinator, permutator, permuted, new_permutator_fn)
}
pub struct KPermutationIterator<'a, T> where T : 'a {
permuted : Vec<&'a T>,
len : usize,
combinator : LargeCombinationIterator<'a, T>,
permutator : Option<HeapPermutationIterator<'a, &'a T>>
}
impl<'a, T> KPermutationIterator<'a, T> {
pub fn new(data : &[T], k : usize) -> KPermutationIterator<T> {
assert_ne!(k, 0);
assert!(k <= data.len());
let combinator = LargeCombinationIterator::new(data, k);
let n = data.len();
let permuted = vec![&data[0]; k];
KPermutationIterator {
permuted : permuted,
len : divide_factorial(n, n - k),
combinator : combinator,
permutator : None
}
}
pub fn into_iter(self) -> Self {
self
}
}
impl<'a, T> Iterator for KPermutationIterator<'a, T> {
type Item = Vec<&'a T>;
fn next(&mut self) -> Option<Vec<&'a T>> {
let combinator = &mut self.combinator;
let permutator = &mut self.permutator;
let permuted = self.permuted.as_mut_slice() as *mut [&T];
unsafe {
if let Some(_) = _k_permutation_next_core(
combinator,
permutator,
&mut *permuted,
#[inline(always)]
|permutator, permuted, comb| {
permuted.copy_from_slice(comb.as_slice());
*permutator = Some(HeapPermutationIterator::new(permuted));
}
) {
Some(self.permuted.to_owned())
} else {
None
}
}
}
}
impl<'a, T> IteratorReset for KPermutationIterator<'a, T> {
fn reset(&mut self) {
self.combinator.reset();
self.permutator = None;
}
}
impl<'a, T> ExactSizeIterator for KPermutationIterator<'a, T> {
fn len(&self) -> usize {
self.len
}
}
pub struct KPermutationCellIter<'a, T> where T : 'a {
permuted : Rc<RefCell<&'a mut [&'a T]>>,
len : usize,
combinator : LargeCombinationIterator<'a, T>,
permutator : Option<HeapPermutationCellIter<'a, &'a T>>
}
impl<'a, T> KPermutationCellIter<'a, T> {
pub fn new(data : &'a [T], k : usize, result : Rc<RefCell<&'a mut [&'a T]>>) -> KPermutationCellIter<'a, T> {
let combinator = LargeCombinationIterator::new(data, k);
let n = data.len();
KPermutationCellIter {
permuted : result,
len : divide_factorial(n, n - k),
combinator : combinator,
permutator : None
}
}
pub fn into_iter(self) -> Self {
self
}
pub fn len(&self) -> usize {
self.len
}
}
impl<'a, T> Iterator for KPermutationCellIter<'a, T> {
type Item = ();
fn next(&mut self) -> Option<()> {
let permutator = &mut self.permutator;
let permuted = Rc::clone(&self.permuted);
if let Some(_) = _k_permutation_next_core(
&mut self.combinator,
permutator,
permuted,
#[inline(always)]
|permutator, permuted, comb| {
permuted.borrow_mut().iter_mut().enumerate().for_each(|(i, p)| *p = comb[i]);
if let Some(p) = permutator {
p.reset();
} else {
*permutator = Some(HeapPermutationCellIter::new(permuted));
}
}) {
return Some(());
} else {
return None;
}
}
}
impl<'a, T> IteratorReset for KPermutationCellIter<'a, T> {
fn reset(&mut self) {
self.combinator.reset();
self.permutator = None;
}
}
impl<'a, T> ExactSizeIterator for KPermutationCellIter<'a, T> {
fn len(&self) -> usize {
self.len
}
}
pub struct KPermutationRefIter<'a, T> where T : 'a {
permuted : *mut [&'a T],
len : usize,
combinator : LargeCombinationIterator<'a, T>,
permutator : Option<HeapPermutationIterator<'a, &'a T>>
}
impl<'a, T> KPermutationRefIter<'a, T> {
pub unsafe fn new(data : &'a [T], k : usize, result : *mut [&'a T]) -> KPermutationRefIter<'a, T> {
let combinator = LargeCombinationIterator::new(data, k);
let n = data.len();
KPermutationRefIter {
permuted : result,
len : divide_factorial(n, n - k),
combinator : combinator,
permutator : None
}
}
pub fn into_iter(self) -> Self {
self
}
pub fn len(&self) -> usize {
self.len
}
}
impl<'a, T> Iterator for KPermutationRefIter<'a, T> {
type Item = ();
fn next(&mut self) -> Option<()> {
let permutator = &mut self.permutator;
let permuted = self.permuted as *mut [&T];
unsafe {
if let Some(_) = _k_permutation_next_core(
&mut self.combinator,
permutator,
&mut *permuted,
#[inline(always)]
|permutator, permuted, comb| {
permuted.iter_mut().enumerate().for_each(|(i, p)| *p = comb[i]);
if let Some(p) = permutator {
p.reset();
} else {
*permutator = Some(HeapPermutationIterator::new(&mut *permuted));
}
}) {
return Some(());
} else {
return None;
}
}
}
}
impl<'a, T> IteratorReset for KPermutationRefIter<'a, T> {
fn reset(&mut self) {
self.combinator.reset();
self.permutator = None;
}
}
impl<'a, T> ExactSizeIterator for KPermutationRefIter<'a, T> {
fn len(&self) -> usize {
self.len
}
}
pub struct SelfCartesianProductIterator<'a, T> where T : 'a {
c : Vec<usize>,
domain : &'a [T],
exhausted : bool,
i : usize,
n : usize,
result : Vec<&'a T>
}
impl<'a, T> SelfCartesianProductIterator<'a, T> where T : 'a {
pub fn new(domain : &'a[T], n : usize) -> SelfCartesianProductIterator<'a, T> {
SelfCartesianProductIterator {
c : vec![0; domain.len()],
domain : domain,
exhausted : false,
i : 0,
n : n,
result : vec![&domain[0]; n]
}
}
pub fn into_iter(self) -> Self {
self
}
}
impl<'a, T> Iterator for SelfCartesianProductIterator<'a, T> {
type Item = Vec<&'a T>;
fn next(&mut self) -> Option<Vec<&'a T>> {
let result = &mut self.result;
let domain = self.domain;
_cartesian_next_core(
&mut self.i,
&mut self.c,
&mut self.exhausted,
self.n,
#[inline(always)]
|_| {
domain.len()
},
#[inline(always)]
|i, j| {
result[i] = &domain[j];
}
);
if self.exhausted {
None
} else {
self.i -= 1; Some(result.to_owned())
}
}
}
impl<'a, T> IteratorReset for SelfCartesianProductIterator<'a, T> {
fn reset(&mut self) {
self.c = vec![0; self.n];
self.exhausted = false;
self.i = 0;
}
}
impl<'a, T> ExactSizeIterator for SelfCartesianProductIterator<'a, T> {
fn len(&self) -> usize {
self.n
}
}
pub struct SelfCartesianProductCellIter<'a, T> where T : 'a {
c : Vec<usize>,
domain : &'a [T],
exhausted : bool,
i : usize,
n : usize,
result : Rc<RefCell<&'a mut [&'a T]>>
}
impl<'a, T> SelfCartesianProductCellIter<'a, T> where T : 'a {
pub fn new(domain : &'a[T], n : usize, result : Rc<RefCell<&'a mut [&'a T]>>) -> SelfCartesianProductCellIter<'a, T> {
SelfCartesianProductCellIter {
c : vec![0; domain.len()],
domain : domain,
exhausted : false,
i : 0,
n : n,
result : Rc::clone(&result)
}
}
pub fn into_iter(self) -> Self {
self
}
}
impl<'a, T> Iterator for SelfCartesianProductCellIter<'a, T> {
type Item = ();
fn next(&mut self) -> Option<()> {
let mut result = self.result.borrow_mut();
let domain = self.domain;
_cartesian_next_core(
&mut self.i,
&mut self.c,
&mut self.exhausted,
self.n,
#[inline(always)]
|_| {
domain.len()
},
#[inline(always)]
|i, j| {
result[i] = &domain[j];
}
);
if self.exhausted {
None
} else {
self.i -= 1; Some(())
}
}
}
impl<'a, T> IteratorReset for SelfCartesianProductCellIter<'a, T> {
fn reset(&mut self) {
self.c = vec![0; self.n];
self.exhausted = false;
self.i = 0;
}
}
impl<'a, T> ExactSizeIterator for SelfCartesianProductCellIter<'a, T> {
fn len(&self) -> usize {
self.n
}
}
pub struct SelfCartesianProductRefIter<'a, T> where T : 'a {
c : Vec<usize>,
domain : &'a [T],
exhausted : bool,
i : usize,
n : usize,
result : &'a mut [&'a T]
}
impl<'a, T> SelfCartesianProductRefIter<'a, T> where T : 'a {
pub unsafe fn new(domain : &'a[T], n : usize, result : * mut [&'a T]) -> SelfCartesianProductRefIter<'a, T> {
SelfCartesianProductRefIter {
c : vec![0; domain.len()],
domain : domain,
exhausted : false,
i : 0,
n : n,
result : &mut *result
}
}
pub fn into_iter(self) -> Self {
self
}
}
impl<'a, T> Iterator for SelfCartesianProductRefIter<'a, T> {
type Item = ();
fn next(&mut self) -> Option<()> {
let result = &mut self.result;
let domain = self.domain;
_cartesian_next_core(
&mut self.i,
&mut self.c,
&mut self.exhausted,
self.n,
#[inline(always)]
|_| {
domain.len()
},
#[inline(always)]
|i, j| {
result[i] = &domain[j];
}
);
if self.exhausted {
None
} else {
self.i -= 1; Some(())
}
}
}
impl<'a, T> IteratorReset for SelfCartesianProductRefIter<'a, T> {
fn reset(&mut self) {
self.c = vec![0; self.n];
self.exhausted = false;
self.i = 0;
}
}
impl<'a, T> ExactSizeIterator for SelfCartesianProductRefIter<'a, T> {
fn len(&self) -> usize {
self.n
}
}
pub trait CartesianProduct<'a> {
type Producer : Iterator;
fn cart_prod(&'a self) -> Self::Producer;
}
impl<'a, T> CartesianProduct<'a> for [&'a [T]]
where T : 'a {
type Producer = CartesianProductIterator<'a, T>;
fn cart_prod(&'a self) -> Self::Producer {
CartesianProductIterator::new(self)
}
}
impl<'a, T> CartesianProduct<'a> for Vec<&'a [T]>
where T : 'a {
type Producer = CartesianProductIterator<'a, T>;
fn cart_prod(&'a self) -> Self::Producer {
CartesianProductIterator::new(self)
}
}
pub type CartesianProductIntoCellParams<'a, T> = (&'a [&'a [T]], Rc<RefCell<&'a mut[&'a T]>>);
impl<'a, 'b: 'a, T> CartesianProduct<'a> for CartesianProductIntoCellParams<'b, T>
where T : 'b {
type Producer = CartesianProductCellIter<'b, T>;
fn cart_prod(&'a self) -> Self::Producer {
CartesianProductCellIter::new(self.0, Rc::clone(&self.1))
}
}
pub type CartesianProductIntoRefParams<'a, T> = (&'a [&'a [T]], *mut [&'a T]);
impl<'a, 'b: 'a, T> CartesianProduct<'a> for CartesianProductIntoRefParams<'b, T>
where T : 'b {
type Producer = CartesianProductRefIter<'b, T>;
fn cart_prod(&'a self) -> Self::Producer {
unsafe {
CartesianProductRefIter::new(self.0, self.1)
}
}
}
pub type SelfCartesianProduct<'a, T> = (&'a [T], usize);
impl<'a, 'b : 'a, T> CartesianProduct<'a> for SelfCartesianProduct<'b, T>
where T : 'b {
type Producer = SelfCartesianProductIterator<'b, T>;
fn cart_prod(&'a self) -> Self::Producer {
SelfCartesianProductIterator::new(self.0, self.1)
}
}
pub type SelfCartesianProductIntoCellParams<'a, T> = (&'a [T], usize, Rc<RefCell<&'a mut [&'a T]>>);
impl<'a, 'b : 'a, T> CartesianProduct<'a> for SelfCartesianProductIntoCellParams<'b, T>
where T : 'b {
type Producer = SelfCartesianProductCellIter<'b, T>;
fn cart_prod(&'a self) -> Self::Producer {
SelfCartesianProductCellIter::new(self.0, self.1, Rc::clone(&self.2))
}
}
pub type SelfCartesianProductIntoRefParams<'a, T> = (&'a [T], usize, *mut [&'a T]);
impl<'a, 'b : 'a, T> CartesianProduct<'a> for SelfCartesianProductIntoRefParams<'b, T>
where T : 'b {
type Producer = SelfCartesianProductRefIter<'b, T>;
fn cart_prod(&'a self) -> Self::Producer {
unsafe {
SelfCartesianProductRefIter::new(self.0, self.1, self.2)
}
}
}
pub trait Combination<'a> {
type Combinator : Iterator;
fn combination(&'a self, k : usize) -> Self::Combinator;
}
impl<'a, T> Combination<'a> for [T] where T : 'a {
type Combinator = LargeCombinationIterator<'a, T>;
fn combination(&'a self, k : usize) -> LargeCombinationIterator<'a, T> {
LargeCombinationIterator::new(self, k)
}
}
impl<'a, T> Combination<'a> for Vec<T> where T : 'a {
type Combinator = LargeCombinationIterator<'a, T>;
fn combination(&'a self, k : usize) -> LargeCombinationIterator<'a, T> {
LargeCombinationIterator::new(self, k)
}
}
pub type CombinationIntoCellParams<'a, T> = (&'a [T], Rc<RefCell<&'a mut[&'a T]>>);
impl<'a, 'b : 'a, T> Combination<'a> for CombinationIntoCellParams<'b, T> {
type Combinator = LargeCombinationCellIter<'b, T>;
fn combination(&'a self, k : usize) -> LargeCombinationCellIter<'b, T> {
LargeCombinationCellIter::new(self.0, k, Rc::clone(&self.1))
}
}
pub type CombinationIntoRefParams<'a, T> = (&'a [T], * mut[&'a T]);
impl<'a, 'b : 'a, T> Combination<'a> for CombinationIntoRefParams<'b, T> {
type Combinator = LargeCombinationRefIter<'b, T>;
fn combination(&'a self, k : usize) -> LargeCombinationRefIter<'b, T> {
unsafe {
LargeCombinationRefIter::new(self.0, k, self.1)
}
}
}
pub trait Permutation<'a> {
type Permutator : Iterator;
fn permutation(&'a mut self) -> Self::Permutator;
}
impl<'a, T> Permutation<'a> for [T] where T : 'a + Clone {
type Permutator = HeapPermutationIterator<'a, T>;
fn permutation(&'a mut self) -> HeapPermutationIterator<T> {
HeapPermutationIterator::new(self)
}
}
impl<'a, T> Permutation<'a> for Vec<T> where T : 'a + Clone {
type Permutator = HeapPermutationIterator<'a, T>;
fn permutation(&'a mut self) -> HeapPermutationIterator<T> {
HeapPermutationIterator::new(self)
}
}
impl<'a, T> Permutation<'a> for Rc<RefCell<&'a mut[T]>> where T :'a {
type Permutator = HeapPermutationCellIter<'a, T>;
fn permutation(&'a mut self) -> HeapPermutationCellIter<T> {
HeapPermutationCellIter {
c : vec![0; self.borrow().len()],
data : Rc::clone(self),
i : 0
}
}
}
impl<'a, T> Permutation<'a> for *mut [T] where T : 'a + Clone {
type Permutator = HeapPermutationRefIter<'a, T>;
fn permutation(&'a mut self) -> HeapPermutationRefIter<T> {
unsafe {
HeapPermutationRefIter {
c : vec![0; (**self).len()],
data : &mut (**self),
i : 0
}
}
}
}
pub type KPermutationParams<'a, T> = (&'a [T], usize);
impl<'a, T> Permutation<'a> for KPermutationParams<'a, T> {
type Permutator = KPermutationIterator<'a, T>;
fn permutation(&'a mut self) -> KPermutationIterator<'a, T> {
KPermutationIterator::new(self.0, self.1)
}
}
pub type KPermutationIntoCellParams<'a, T> = (&'a [T], usize, Rc<RefCell<&'a mut [&'a T]>>);
impl<'a, 'b : 'a, T> Permutation<'a> for KPermutationIntoCellParams<'b, T> {
type Permutator = KPermutationCellIter<'b, T>;
fn permutation(&'a mut self) -> Self::Permutator {
KPermutationCellIter::new(self.0, self.1, Rc::clone(&self.2))
}
}
pub type KPermutationIntoRefParams<'a, T> = (&'a [T], usize, *mut [&'a T]);
impl<'a, 'b : 'a, T> Permutation<'a> for KPermutationIntoRefParams<'b, T> {
type Permutator = KPermutationRefIter<'b, T>;
fn permutation(&'a mut self) -> Self::Permutator {
unsafe {
KPermutationRefIter::new(self.0, self.1, &mut *self.2)
}
}
}
#[allow(unused)]
fn gosper_combination(x : &mut u128) -> Option<()> {
let u = *x & x.overflowing_neg().0; let v = u + *x; if v == 0 {
return None
}
*x = v + (((v ^ *x) / u) >> 2);
Some(())
}
#[inline(always)]
fn stanford_combination(x: &mut u128) {
let t = *x | (*x - 1); *x = (t + 1) | (((!t & (!t).overflowing_neg().0) - 1) >> (x.trailing_zeros() + 1));
}
pub fn factorial<T>(n: T) -> T where T : PrimInt + Unsigned + Product {
num::range(T::one(), n + T::one()).product()
}
pub fn divide_factorial<T>(numerator: T, denominator: T) -> T where T : PrimInt + Unsigned + Product {
if numerator < denominator {
T::one()
} else if denominator < numerator {
num::range_inclusive(denominator + T::one(), numerator).product()
} else {
T::one()
}
}
pub fn multiply_factorial<T>(fact1: T, fact2: T) -> T where T : PrimInt + Unsigned + Product {
if fact1 < fact2 {
let common = factorial(fact1);
common.pow(2) * num::range_inclusive(fact1 + T::one(), fact2).product()
} else if fact2 < fact1 {
let common = factorial(fact2);
common.pow(2) * num::range_inclusive(fact2 + T::one(), fact1).product()
} else {
return factorial(fact1).pow(2);
}
}
fn create_k_set<T>(d : &[T], width : usize) -> (Vec<&T>, u128) {
let mask = (1 << width) - 1;
let mut copied_mask = mask;
let mut i = 0;
let mut subset = Vec::new();
while copied_mask > 0 {
if copied_mask & 1 == 1 {
subset.push(&d[i]);
}
i += 1;
copied_mask >>= 1;
}
(subset, mask)
}
unsafe fn unsafe_create_k_set<'a, T>(d : &'a[T], width : usize, result : *mut [&'a T], mask : &mut u128) {
*mask = (1 << width) - 1;
let mut copied_mask = *mask;
let mut i = 0;
let mut j = 0;
while copied_mask > 0 {
if copied_mask & 1 == 1 {
(*result)[j] = &d[i];
j += 1;
}
i += 1;
copied_mask >>= 1;
}
}
fn create_k_set_in_cell<'a, T>(d : &'a[T], width : usize, result : &Rc<RefCell<&'a mut[&'a T]>>, mask : &mut u128) {
*mask = (1 << width) - 1;
let mut copied_mask = *mask;
let mut i = 0;
let mut j = 0;
while copied_mask > 0 {
if copied_mask & 1 == 1 {
result.borrow_mut()[j] = &d[i];
j += 1;
}
i += 1;
copied_mask >>= 1;
}
}
fn create_k_set_sync<'a, T>(d : &'a[T], width : usize, result : &Arc<RwLock<Vec<&'a T>>>, mask : &mut u128) {
*mask = (1 << width) - 1;
let mut copied_mask = *mask;
let mut i = 0;
let mut j = 0;
while copied_mask > 0 {
if copied_mask & 1 == 1 {
result.write().unwrap()[j] = &d[i];
j += 1;
}
i += 1;
copied_mask >>= 1;
}
}
#[inline(always)]
fn swap_k<'a, 'b : 'a, 'c : 'b, T : 'c>(subset_map : (&'a mut [&'b T], &mut u128), d : &'c[T]) -> Option<()> {
stanford_combination(subset_map.1);
let mut copied_mask = *subset_map.1;
let n = d.len();
let mut i = 0;
let mut j = 0;
while copied_mask > 0 && i < n {
if copied_mask & 1 == 1 {
subset_map.0[j] = &d[i];
j += 1;
}
i += 1;
copied_mask >>= 1;
}
if copied_mask > 0 { None
} else {
Some(())
}
}
fn swap_k_in_cell<'a, 'b : 'a, T>(subset_map : (&Rc<RefCell<&'a mut [&'b T]>>, &mut u128), d : &'b[T]) -> Option<()> {
stanford_combination(subset_map.1);
let mut copied_mask = *subset_map.1;
let n = d.len();
let mut i = 0;
let mut j = 0;
while copied_mask > 0 && i < n {
if copied_mask & 1 == 1 {
subset_map.0.borrow_mut()[j] = &d[i];
j += 1;
}
i += 1;
copied_mask >>= 1;
}
if copied_mask > 0 { None
} else {
Some(())
}
}
fn swap_k_sync<'a, 'b : 'a, T>(subset_map : (&Arc<RwLock<Vec<&'b T>>>, &mut u128), d : &'b[T]) -> Option<()> {
stanford_combination(subset_map.1);
let mut copied_mask = *subset_map.1;
let n = d.len();
let mut i = 0;
let mut j = 0;
while copied_mask > 0 && i < n {
if copied_mask & 1 == 1 {
subset_map.0.write().unwrap()[j] = &d[i];
j += 1;
}
i += 1;
copied_mask >>= 1;
}
if copied_mask > 0 { None
} else {
Some(())
}
}
#[cfg(test)]
pub mod test {
use super::*;
use std::thread;
use std::sync::mpsc;
use std::sync::mpsc::{SyncSender, Receiver};
#[test]
fn test_get_cartesian_for() {
let words = ["word1", "word2", "word3"];
let result = [[&words[0], &words[0]], [&words[0], &words[1]],
[&words[0], &words[2]], [&words[1], &words[0]],
[&words[1], &words[1]], [&words[1], &words[2]],
[&words[2], &words[0]], [&words[2], &words[1]],
[&words[2], &words[2]]];
for (i, r) in result.iter().enumerate() {
assert_eq!(get_cartesian_for(&words, 2, i).unwrap(), r, "Fail to get cartesian product degree 2@i={}", i);
}
assert_eq!(get_cartesian_for(&words, 4, 0).is_err(), true, "Unexpected no error when degree is larger than size of objects");
for (i, w) in words.iter().enumerate() {
assert_eq!(get_cartesian_for(&words, 1, i).unwrap()[0], w, "Fail to get cartesian product degree 1@i={}", i);
}
assert_eq!(get_cartesian_for(&words, 0, 0).unwrap().len(), 0, "Fail to get cartesian product degree 0");
}
#[test]
fn test_get_permutation_for() {
let words = ["word1", "word2", "word3"];
let result = [[&words[0], &words[1]], [&words[0], &words[2]],
[&words[1], &words[0]], [&words[1], &words[2]],
[&words[2], &words[0]], [&words[2], &words[1]]];
for (i, r) in result.iter().enumerate() {
assert_eq!(get_permutation_for(&words, 2, i).unwrap(), r, "Fail to get permutation degree 2@i={}", i);
}
assert_eq!(get_permutation_for(&words, 4, 0).is_err(), true, "Unexpected no error when degree is larger than size of objects");
for (i, w) in words.iter().enumerate() {
assert_eq!(get_permutation_for(&words, 1, i).unwrap()[0], w, "Fail to get permutation degree 1@i={}", i);
}
assert_eq!(get_permutation_for(&words, 0, 0).unwrap().len(), 0, "Fail to get permutation degree 0");
}
#[test]
fn test_heap_permutation_6() {
let mut data = [1, 2, 3, 4, 5, 6];
let mut counter = 1;
heap_permutation(&mut data, |_| {
counter +=1;
});
assert_eq!(720, counter);
}
#[test]
fn test_heap_permutation_10() {
use std::time::{Instant};
let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let mut counter = 1;
let timer = Instant::now();
heap_permutation(&mut data, |_| {
counter += 1;
});
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
assert_eq!(3628800, counter);
}
#[allow(non_snake_case, unused)]
#[test]
fn test_CartesianProduct() {
use std::time::Instant;
let data : &[&[usize]] = &[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]];
let cart = CartesianProductIterator::new(&data);
let mut counter = 0;
let timer = Instant::now();
for p in cart {
counter += 1;
}
assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
println!("Total {} products done in {:?}", counter, timer.elapsed());
}
#[allow(non_snake_case, unused)]
#[test]
fn test_SelfCartesianProduct() {
use std::time::Instant;
let data : &[usize] = &[1, 2, 3];
let n = 3;
let cart = SelfCartesianProductIterator::new(&data, n);
let mut counter = 0;
let timer = Instant::now();
for p in cart {
println!("{:?}", p);
counter += 1;
}
assert_eq!(data.len().pow(n as u32), counter);
println!("Total {} products done in {:?}", counter, timer.elapsed());
}
#[allow(non_snake_case, unused)]
#[test]
fn test_CartesianProduct_reset() {
use std::time::Instant;
let data : &[&[usize]] = &[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]];
let mut counter = 0;
let mut result : Vec<&usize> = vec![&data[0][0]; data.len()];
unsafe {
let mut cart = CartesianProductRefIter::new(&data, result.as_mut_slice());
let timer = Instant::now();
while let Some(_) = cart.next() {
counter += 1;
}
let all_possible = data.iter().fold(1, |cum, domain| {cum * domain.len()});
assert_eq!(all_possible, counter);
counter = 0;
while let Some(_) = cart.next() {
counter += 1;
}
assert_eq!(0, counter);
cart.reset();
counter = 0;
for _ in cart {
counter += 1;
}
assert_eq!(all_possible, counter);
println!("Total {} products done in {:?}", counter, timer.elapsed());
}
}
#[allow(non_snake_case, unused)]
#[test]
fn test_CartesianProduct_mimic_iterator() {
use std::time::Instant;
let data : &[&[usize]] = &[&[1, 2], &[3, 4, 5, 6], &[7, 8, 9], &[10, 11, 12,]];
let mut result : Vec<&usize> = vec![&data[0][0]; data.len()];
unsafe {
let mut cart = CartesianProductRefIter::new(&data, result.as_mut_slice());
let mut counter = 0;
let timer = Instant::now();
for _ in cart {
counter += 1;
}
assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
println!("Total {} products done in {:?}", counter, timer.elapsed());
}
}
#[allow(non_snake_case, unused)]
#[test]
fn test_SelfCartesianProduct_cell() {
use std::time::Instant;
let data : &[usize] = &[1, 2, 3];
let n = 3;
let mut result = vec![&data[0]; n];
let shared = Rc::new(RefCell::new(result.as_mut_slice()));
let cart = SelfCartesianProductCellIter::new(&data, n, Rc::clone(&shared));
let mut counter = 0;
let timer = Instant::now();
for _ in cart {
println!("{:?}", &*shared.borrow());
counter += 1;
}
assert_eq!(data.len().pow(n as u32), counter);
println!("Total {} products done in {:?}", counter, timer.elapsed());
}
#[allow(non_snake_case, unused)]
#[test]
fn test_SelfCartesianProduct_ref() {
use std::time::Instant;
let data : &[usize] = &[1, 2, 3];
let n = 3;
let result : &mut[&usize] = &mut vec![&data[0]; n];
let shared = result as *mut[&usize];
unsafe {
let cart = SelfCartesianProductRefIter::new(&data, n, result);
let mut counter = 0;
let timer = Instant::now();
for _ in cart {
println!("{:?}", &*shared);
counter += 1;
}
assert_eq!(data.len().pow(n as u32), counter);
println!("Total {} products done in {:?}", counter, timer.elapsed());
}
}
#[allow(non_snake_case, unused)]
#[test]
fn test_CartesianProduct_mimic_iterator_2() {
use std::time::Instant;
let data : &[&[usize]] = &[&[1, 2], &[3, 4, 5, 6], &[7, 8, 9], &[10, 11, 12,]];
let mut result : Vec<&usize> = vec![&data[0][0]; data.len()];
unsafe {
let mut cart = CartesianProductRefIter::new(&data, result.as_mut_slice() as *mut [&usize]);
let mut counter = 0;
let timer = Instant::now();
for _ in cart {
counter += 1;
}
assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
println!("Total {} products done in {:?}", counter, timer.elapsed());
}
}
#[allow(non_snake_case, unused)]
#[test]
fn test_CartesianProduct_trait() {
use std::time::Instant;
let mut counter = 0;
let timer = Instant::now();
let data : &[&[u8]]= &[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]];
data.cart_prod().for_each(|p| {
counter += 1;
});
assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
println!("Total {} products done in {:?}", counter, timer.elapsed());
}
#[allow(non_snake_case, unused)]
#[test]
fn test_CartesianProduct_shared_trait() {
use std::time::Instant;
let mut counter = 0;
let timer = Instant::now();
let data : &[&[u8]]= &[&[1, 2], &[3, 4, 5, 6], &[7, 8, 9], &[10, 11, 12,]];;
let mut result = vec![&data[0][0]; data.len()];
let shared = Rc::new(RefCell::new(result.as_mut_slice()));
(data, Rc::clone(&shared)).cart_prod().for_each(|_| {
counter += 1;
});
assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
println!("Total {} products done in {:?}", counter, timer.elapsed());
}
#[allow(non_snake_case, unused)]
#[test]
fn test_CartesianProduct_ptr_trait() {
use std::time::Instant;
let mut counter = 0;
let timer = Instant::now();
let data : &[&[u8]]= &[&[1, 2], &[3, 4, 5, 6], &[7, 8, 9], &[10, 11, 12,]];;
let mut result = vec![&data[0][0]; data.len()];
let shared = result.as_mut_slice() as *mut [&u8];
(data, shared).cart_prod().for_each(|_| {
counter += 1;
});
assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
println!("Total {} products done in {:?}", counter, timer.elapsed());
}
#[allow(unused)]
#[test]
fn test_k_permutation_fn() {
use std::time::{Instant};
let data = [1, 2, 3, 4, 5];
let k = 3;
let mut counter = 0;
let timer = Instant::now();
k_permutation(&data, k, |permuted| {
println!("{}:{:?}", counter, permuted);
counter += 1;
});
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
}
#[allow(unused)]
#[should_panic]
#[test]
fn test_k_permutation_empty_dom() {
use std::time::{Instant};
let data : &[i32] = &[];
let k = 1;
let mut counter = 0;
let timer = Instant::now();
k_permutation(&data, k, |permuted| {
println!("{}:{:?}", counter, permuted);
counter += 1;
});
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
}
#[allow(unused)]
#[test]
fn test_k_permutation_k_1() {
use std::time::{Instant};
let data : &[i32] = &[1, 2];
let k = 1;
let mut counter = 0;
let timer = Instant::now();
k_permutation(&data, k, |permuted| {
println!("{}:{:?}", counter, permuted);
counter += 1;
});
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
}
#[allow(unused)]
#[test]
#[ignore]
fn test_large_k_permutation() {
use std::time::{Instant};
let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
let k = 11;
let mut counter = 0;
let timer = Instant::now();
k_permutation(&data, k, |permuted| {
counter += 1;
});
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
}
#[allow(non_snake_case, unused)]
#[test]
fn test_HeapPermutation() {
use std::time::{Instant};
let mut data : Vec<String> = (1..=3).map(|num| {format!("some ridiculously long word prefix without any point{}", num)}).collect();
let mut permutator = HeapPermutationIterator::new(&mut data);
let timer = Instant::now();
let mut counter = 1;
while let Some(permutated) = permutator.next() {
counter += 1;
}
assert_eq!(6, counter);
println!("Done {} permutations in {:?}", counter, timer.elapsed());
}
#[allow(non_snake_case, unused)]
#[test]
fn test_HeapPermutation_reset() {
use std::time::{Instant};
let mut data : Vec<String> = (1..=3).map(|num| {format!("some ridiculously long word prefix without any point{}", num)}).collect();
println!("0:{:?}", data);
let mut permutator = HeapPermutationIterator::new(&mut data);
let timer = Instant::now();
let mut counter = 1;
while let Some(permutated) = permutator.next() {
counter += 1;
}
assert_eq!(6, counter);
let mut counter = 1;
while let Some(permutated) = permutator.next() {
counter += 1;
}
assert_eq!(1, counter);
permutator.reset();
let mut counter = 1;
while let Some(permutated) = permutator.next() {
counter += 1;
}
assert_eq!(6, counter);
}
#[allow(non_snake_case, unused)]
#[test]
fn test_HeapPermutationIterator() {
use std::time::{Instant};
let mut data : Vec<String> = (1..=3).map(|num| {format!("some ridiculously long word prefix without any point{}", num)}).collect();
println!("0:{:?}", data);
let permutator = HeapPermutationIterator::new(&mut data);
let timer = Instant::now();
let mut counter = 1;
for permutated in permutator {
println!("{}:{:?}", counter, permutated);
counter += 1;
}
println!("Done {} permutations in {:?}", counter, timer.elapsed());
assert_eq!(6, counter);
}
#[allow(non_snake_case, unused)]
#[test]
fn test_HeapPermutationIntoIterator() {
use std::time::{Instant};
let mut data : Vec<String> = (1..=3).map(|num| {format!("some ridiculously long word prefix without any point{}", num)}).collect();
println!("0:{:?}", data);
let permutator = HeapPermutationIterator::new(&mut data);
let timer = Instant::now();
let mut counter = 1;
permutator.into_iter().for_each(|permutated| {counter += 1;});
println!("Done {} permutations in {:?}", counter, timer.elapsed());
assert_eq!(6, counter);
}
#[allow(non_snake_case, unused)]
#[test]
fn test_HeapPermutationRefIterator() {
use std::time::{Instant};
let mut data : Vec<String> = (1..=3).map(|num| {format!("some ridiculously long word prefix without any point{}", num)}).collect();
unsafe {
let mut permutator = HeapPermutationRefIter::new(data.as_mut_slice());
let timer = Instant::now();
let mut counter = 1;
while let Some(permutated) = permutator.next() {
counter += 1;
}
assert_eq!(6, counter);
println!("Done perm_ref {} permutations in {:?}", counter, timer.elapsed());
}
}
#[allow(non_snake_case, unused)]
#[test]
fn test_HeapPermutationCellIterIterator() {
use std::time::{Instant};
let mut data : Vec<String> = (1..=3).map(|num| {format!("some ridiculously long word prefix without any point{}", num)}).collect();
let shared = Rc::new(RefCell::new(data.as_mut_slice()));
let permutator = HeapPermutationCellIter::new(Rc::clone(&shared));
println!("{}:{:?}", 0, &*shared.borrow());
let timer = Instant::now();
let mut counter = 1;
for _ in permutator {
println!("{}:{:?}", counter, &*shared.borrow());
counter += 1;
}
println!("Done {} permutations in {:?}", counter, timer.elapsed());
assert_eq!(6, counter);
}
#[allow(non_snake_case, unused)]
#[test]
fn test_GosperCombinationIterator() {
use std::time::{Instant};
let gosper = GosperCombinationIterator::new(&[1, 2, 3, 4, 5], 3);
let mut counter = 0;
let timer = Instant::now();
for combination in gosper {
counter += 1;
}
println!("Total {} combinations in {:?}", counter, timer.elapsed());
assert_eq!(10, counter);
}
#[allow(non_snake_case, unused)]
#[test]
fn test_LargeCombinationIterator() {
use std::time::{Instant};
let data : &[i32] = &[1, 2, 3, 4, 5];
let k = 3;
let mut combs = LargeCombinationIterator::new(data, k);
let mut counter = 0;
let timer = Instant::now();
for combination in combs.iter() {
println!("{}:{:?}", counter, combination);
counter += 1;
}
println!("Total {} combinations in {:?}", counter, timer.elapsed());
assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
for combination in combs.iter() {
println!("{}:{:?}", counter, combination);
counter += 1;
}
assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
combs.reset();
let mut counter = 0;
let timer = Instant::now();
for combination in combs.iter() {
println!("{}:{:?}", counter, combination);
counter += 1;
}
println!("Total {} combinations in {:?}", counter, timer.elapsed());
assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
}
#[allow(non_snake_case, unused)]
#[test]
fn test_LargeCombinationIterator_single() {
use std::time::{Instant};
let data : &[i32] = &[1, 2, 3, 4, 5];
let k = 1;
let mut combs = LargeCombinationIterator::new(data, k);
let mut counter = 0;
let timer = Instant::now();
for combination in combs.iter() {
println!("{}:{:?}", counter, combination);
counter += 1;
}
println!("Total {} combinations in {:?}", counter, timer.elapsed());
assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
for combination in combs.iter() {
println!("{}:{:?}", counter, combination);
counter += 1;
}
assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
combs.reset();
let mut counter = 0;
let timer = Instant::now();
for combination in combs.iter() {
println!("{}:{:?}", counter, combination);
counter += 1;
}
println!("Total {} combinations in {:?}", counter, timer.elapsed());
assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
}
#[allow(non_snake_case, unused)]
#[test]
fn test_GosperCombinationIteratorUnsafe() {
use std::time::{Instant};
let data = &[1, 2, 3, 4, 5, 6];
let r = 4;
let mut counter = 0;
let timer = Instant::now();
let mut result = vec![&data[0]; r];
unsafe {
let mut gosper = GosperCombinationRefIter::new(data, r, result.as_mut_slice() as *mut [&i32]);
for _ in gosper {
counter += 1;
}
println!("Total {} combinations in {:?}", counter, timer.elapsed());
assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
}
}
#[allow(non_snake_case, unused)]
#[test]
fn test_GosperCombinationCellIter() {
use std::time::{Instant};
let data = &[1, 2, 3, 4, 5, 6];
let r = 3;
let mut counter = 0;
let timer = Instant::now();
let mut result = vec![&data[0]; r];
let shared = Rc::new(RefCell::new(result.as_mut_slice()));
let mut gosper = GosperCombinationCellIter::new(data, r, Rc::clone(&shared));
for _ in gosper {
counter += 1;
}
println!("Total {} combinations in {:?}", counter, timer.elapsed());
assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
}
#[allow(non_snake_case, unused)]
#[test]
fn test_GosperCombinationIteratorAlike_reset() {
use std::time::{Instant};
let data = &[1, 2, 3, 4, 5];
let r = 3;
let mut counter = 0;
let timer = Instant::now();
let mut result = vec![&data[0]; r];
unsafe {
let mut gosper = GosperCombinationRefIter::new(data, r, result.as_mut_slice() as *mut [&i32]);
let mut iter = gosper.into_iter();
while let Some(_) = iter.next() {
println!("{}:{:?}", counter, result);
counter += 1;
}
println!("Total {} combinations in {:?}", counter, timer.elapsed());
let all_possible = divide_factorial(data.len(), r) / factorial(data.len() - r);
assert_eq!(all_possible, counter);
counter = 0;
while let Some(_) = iter.next() {
counter += 1;
}
assert_eq!(0, counter);
iter.reset();
counter = 0;
while let Some(_) = iter.next() {
counter += 1;
}
assert_eq!(all_possible, counter);
}
}
#[allow(non_snake_case, unused)]
#[test]
fn test_KPermutationIterator() {
use std::time::Instant;
let data = [1, 2, 3, 4, 5];
let k = 3;
let permutator = KPermutationIterator::new(&data, k);
let mut counter = 0;
let timer = Instant::now();
for permuted in permutator {
println!("{}:{:?}", counter, permuted);
counter += 1;
}
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
}
#[allow(non_snake_case, unused)]
#[test]
fn test_KPermutationIteratorBound() {
use std::time::Instant;
let data = [1, 2, 3, 4];
let k = 4;
let permutator = KPermutationIterator::new(&data, k);
let mut counter = 0;
let timer = Instant::now();
for permuted in permutator {
println!("{}:{:?}", counter, permuted);
counter += 1;
}
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
}
#[allow(non_snake_case)]
#[test]
fn test_KPermutation_into_Cell() {
use std::time::Instant;
let data : &[i32] = &[1, 2, 3, 4, 5];
let mut counter = 0;
let k = 3;
let mut result : Vec<&i32> = vec![&data[0]; k];
let shared = Rc::new(RefCell::new(result.as_mut_slice()));
let timer = Instant::now();
KPermutationCellIter::new(data, k, Rc::clone(&shared)).into_iter().for_each(|_| {
counter += 1;
});
println!("Total {} combination done in {:?}", counter, timer.elapsed());
assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
}
#[allow(non_snake_case)]
#[test]
fn test_KPermutation_into_Ref() {
use std::time::Instant;
let data : &[i32] = &[1, 2, 3, 4, 5];
let mut counter = 0;
let k = 3;
let mut result : Vec<&i32> = vec![&data[0]; k];
let shared = result.as_mut_slice() as *mut [&i32];
let timer = Instant::now();
unsafe {
KPermutationRefIter::new(data, k, shared).into_iter().for_each(|_| {
counter += 1;
});
println!("Total {} combination done in {:?}", counter, timer.elapsed());
assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
}
}
#[allow(unused)]
#[test]
fn test_cartesian_product() {
use std::time::Instant;
let set = (1..4).map(|item| item).collect::<Vec<u64>>();
let mut data = Vec::<&[u64]>::new();
for _ in 0..4 {
data.push(&set);
}
let mut counter = 0;
let timer = Instant::now();
cartesian_product(&data, |product| {
counter += 1;
});
println!("Total {} product done in {:?}", counter, timer.elapsed());
}
#[allow(unused)]
#[test]
fn test_self_cartesian_product() {
use std::time::Instant;
let data : &[i32] = &[1, 2, 3];
let n = 3;
let mut counter = 0;
let timer = Instant::now();
self_cartesian_product(&data, 3, |product| {
println!("{:?}", product);
counter += 1;
});
println!("Total {} product done in {:?}", counter, timer.elapsed());
}
#[allow(unused)]
#[should_panic]
#[test]
fn test_self_cartesian_product_zero() {
use std::time::Instant;
let data : &[i32] = &[1, 2, 3];
let n = 0;
let mut counter = 0;
let timer = Instant::now();
self_cartesian_product(&data, n, |product| {
println!("{:?}", product);
counter += 1;
});
println!("Total {} product done in {:?}", counter, timer.elapsed());
}
#[test]
fn test_combination_trait() {
let data = [1, 2, 3, 4, 5, 6, 7, 8];
let k = 4;
let mut counter = 0;
for combination in data.combination(k) {
println!("{:?}", combination);
counter += 1;
}
assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); }
#[test]
fn test_combination_trait_share() {
let data : &[i32] = &[1, 2, 3, 4, 5, 6, 7, 8];
let k = 3;
let mut result = vec![&data[0]; k];
let shared = Rc::new(RefCell::new(result.as_mut_slice()));
let combination_op = (data, shared);
let mut counter = 0;
for combination in combination_op.combination(k) {
println!("{:?}", combination);
counter += 1;
}
assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); }
#[test]
fn test_combination_trait_ptr() {
let data : &[i32] = &[1, 2, 3, 4, 5, 6];
let k = 4;
let mut result = vec![&data[0]; k];
let shared = result.as_mut_slice() as *mut [&i32];
let combination_op = (data, shared);
let mut counter = 0;
unsafe {
for _ in combination_op.combination(k) {
println!("{:?}", &*shared);
counter += 1;
}
}
assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); }
#[test]
fn test_large_combination_fn_k_1() {
let data : &[i32] = &[1, 2, 3, 4, 5, 6];
let k = 1;
let mut counter = 0;
large_combination(data, k, |_result| {
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); }
#[should_panic]
#[test]
fn test_large_combination_fn_k_0() {
let data : &[i32] = &[1, 2, 3, 4, 5, 6];
let k = 0;
let mut counter = 0;
large_combination(data, k, |_result| {
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); }
#[test]
fn test_large_combination_fn_d_eq_k() {
let data : &[i32] = &[1, 2, 3];
let k = 3;
let mut counter = 0;
large_combination(data, k, |_result| {
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); }
#[test]
fn test_large_combination_fn() {
let data : &[i32] = &[1, 2, 3, 4, 5];
let k = 3;
let mut counter = 0;
large_combination(data, k, |_result| {
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); }
#[test]
fn test_permutation_trait() {
let mut data = [1, 2, 3, 4, 5];
println!("{:?}", data);
let mut counter = 1;
for permuted in data.permutation() {
println!("{:?}", permuted);
counter += 1;
}
assert_eq!(counter, factorial(data.len()));
}
#[test]
fn test_permutation_trait_cell() {
let data : &mut[i32] = &mut [1, 2, 3, 4, 5];
let mut shared = Rc::new(RefCell::new(data));
let value = Rc::clone(&shared);
println!("{:?}", &*shared.borrow());
let mut counter = 1;
shared.permutation().for_each(|_| {
println!("{:?}", &*value.borrow());
counter += 1;
});
assert_eq!(counter, factorial(value.borrow().len()));
}
#[test]
fn test_permutation_trait_ref() {
let data : &mut[i32] = &mut [1, 2, 3, 4, 5];
let mut shared = data as *mut [i32];
let mut counter = 1;
shared.permutation().for_each(|_| {
println!("{:?}", data);
counter += 1;
});
assert_eq!(counter, factorial(data.len()));
}
#[test]
fn test_k_permutation_primitive() {
let data = [1, 2, 3, 4, 5];
let k = 3;
let mut counter = 0;
data.combination(k).for_each(|mut combination| {
println!("{:?}", combination);
counter += 1;
combination.permutation().for_each(|permuted| {
println!("{:?}", permuted);
counter += 1;
});
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
}
#[allow(non_snake_case)]
#[test]
fn test_KPermutation_trait() {
let data : &mut[i32] = &mut [1, 2, 3, 4, 5];
let mut counter = 0;
(&*data, 3usize).permutation().for_each(|_p| {
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - 3));
}
#[allow(non_snake_case)]
#[test]
fn test_KPermutation_single() {
let data : &mut[i32] = &mut [1, 2, 3, 4, 5];
let mut counter = 0;
(&*data, 1usize).permutation().for_each(|_p| {
println!("{:?}", _p);
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - 3));
}
#[allow(non_snake_case)]
#[test]
fn test_KPermutation_into_cell_trait() {
use std::time::Instant;
let data : &mut[i32] = &mut [1, 2, 3, 4, 5, 6];
let mut counter = 0;
let k = 2;
let mut result : Vec<&i32> = vec![&data[0]; k];
let shared = Rc::new(RefCell::new(result.as_mut_slice()));
let timer = Instant::now();
(&*data, k, Rc::clone(&shared)).permutation().for_each(|_| {
counter += 1;
});
println!("Total {} combination done in {:?}", counter, timer.elapsed());
assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
}
#[allow(non_snake_case, unused_unsafe)]
#[test]
fn test_KPermutation_into_Ref_trait() {
use std::time::Instant;
let data : &[i32] = &[1, 2, 3, 4, 5];
let mut counter = 0;
let k = 3;
let mut result : Vec<&i32> = vec![&data[0]; k];
let shared = result.as_mut_slice() as *mut [&i32];
let timer = Instant::now();
unsafe {
(data, k, shared).permutation().for_each(|_| {
counter += 1;
});
println!("Total {} combination done in {:?}", counter, timer.elapsed());
assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
}
}
#[test]
fn test_combination_fn() {
let data = [1, 2, 3, 4, 5];
let r = 3;
let mut counter = 0;
combination(&data, r, |comb| {
println!("{:?}", comb);
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
}
#[test]
fn test_combination_fn_single() {
let data = [1];
let r = 1;
let mut counter = 0;
combination(&data, r, |comb| {
println!("{:?}", comb);
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
}
#[test]
fn test_combination_fn_bound() {
let data = [1, 2, 3];
let r = 3;
let mut counter = 0;
combination(&data, r, |comb| {
println!("{:?}", comb);
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
}
#[test]
fn test_large_combination_cell_fn() {
let data : &mut [i32] = &mut [1, 2, 3, 4, 5];
let r = 3;
let mut counter = 0;
let mut result : Vec<&i32> = vec![&data[0]; r];
let shared : Rc<RefCell<&mut [&i32]>> = Rc::new(RefCell::new(&mut result));
large_combination_cell(&data, r, Rc::clone(&shared), || {
println!("{:?}", shared.borrow());
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
}
#[test]
fn test_large_combination_sync_fn() {
let data : &mut [i32] = &mut [1, 2, 3, 4, 5];
let r = 3;
let mut counter = 0;
let result : Vec<&i32> = vec![&data[0]; r];
let shared : Arc<RwLock<Vec<&i32>>> = Arc::new(RwLock::new(result));
large_combination_sync(&data, r, Arc::clone(&shared), || {
println!("{:?}", shared.read().unwrap());
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
}
#[test]
fn test_unsafe_combination_fn() {
let data = [1, 2, 3, 4, 5];
let r = 3;
let mut counter = 0;
let mut result = vec![&data[0]; r];
let result_ptr = result.as_mut_slice() as *mut [&usize];
unsafe {
unsafe_combination(&data, r, result_ptr, || {
println!("{:?}", result);
counter += 1;
});
}
assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
}
#[test]
fn test_combination_cell_fn() {
let data = [1, 2, 3, 4, 5];
let r = 3;
let mut counter = 0;
let mut result = vec![&data[0]; r];
let result_cell = Rc::new(RefCell::new(result.as_mut_slice()));
combination_cell(&data, r, Rc::clone(&result_cell), || {
println!("{:?}", result_cell.borrow());
counter += 1;
});
assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
}
#[test]
fn test_unsafe_shared_combination_result_fn() {
use std::fmt::Debug;
trait Consumer {
fn consume(&self);
}
struct Worker1<'a, T : 'a> {
data : &'a[&'a T]
}
impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
fn consume(&self) {
self.data.iter().for_each(|_| {});
}
}
struct Worker2<'a, T : 'a> {
data : &'a[&'a T]
}
impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
fn consume(&self) {
self.data.iter().for_each(|_| {});
}
}
unsafe fn start_combination_process<'a>(data : &'a[i32], cur_result : *mut [&'a i32], k : usize, consumers : Vec<Box<Consumer + 'a>>) {
use std::time::Instant;
let timer = Instant::now();
let mut counter = 0;
unsafe_combination(data, k, cur_result, || {
consumers.iter().for_each(|c| {
c.consume();
});
counter += 1;
});
println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
}
let k = 5;
let data = &[1, 2, 3, 4, 5, 6];
let mut result = vec![&data[0]; k];
unsafe {
let shared = result.as_mut_slice() as *mut [&i32];
let worker1 = Worker1 {
data : &result
};
let worker2 = Worker2 {
data : &result
};
let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
start_combination_process(data, shared, k, consumers);
}
}
#[test]
fn test_shared_combination_result_fn() {
use std::fmt::Debug;
trait Consumer {
fn consume(&self);
}
struct Worker1<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
fn consume(&self) {
let result = self.data.borrow();
result.iter().for_each(|_| {});
}
}
struct Worker2<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
fn consume(&self) {
let result = self.data.borrow();
result.iter().for_each(|_| {});
}
}
fn start_combination_process<'a>(data : &'a[i32], cur_result : Rc<RefCell<&'a mut[&'a i32]>>, k : usize, consumers : Vec<Box<Consumer + 'a>>) {
use std::time::Instant;
let timer = Instant::now();
let mut counter = 0;
combination_cell(data, k, cur_result, || {
consumers.iter().for_each(|c| {
c.consume();
});
counter += 1;
});
println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
}
let k = 4;
let data = &[1, 2, 3, 4, 5, 6, 7];
let mut result = vec![&data[0]; k];
let result_cell = Rc::new(RefCell::new(result.as_mut_slice()));
let worker1 = Worker1 {
data : Rc::clone(&result_cell)
};
let worker2 = Worker2 {
data : Rc::clone(&result_cell)
};
let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
start_combination_process(data, result_cell, k, consumers);
}
#[test]
fn test_shared_combination_result_sync_fn() {
fn start_combination_process<'a>(data : &'a[i32], cur_result : Arc<RwLock<Vec<&'a i32>>>, k : usize, notifier : Vec<SyncSender<Option<()>>>, release_recv : Receiver<()>) {
use std::time::Instant;
let timer = Instant::now();
let mut counter = 0;
combination_sync(data, k, cur_result, || {
notifier.iter().for_each(|n| {
n.send(Some(())).unwrap(); });
for _ in 0..notifier.len() {
release_recv.recv().unwrap(); }
counter += 1;
});
notifier.iter().for_each(|n| {n.send(None).unwrap()});
println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
}
let k = 4;
let data = &[1, 2, 3, 4, 5, 6];
let result = vec![&data[0]; k];
let result_sync = Arc::new(RwLock::new(result));
let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
let (main_send, main_recv) = mpsc::sync_channel(0);
let t1_local = main_send.clone();
let t1_dat = Arc::clone(&result_sync);
thread::spawn(move || {
while let Some(_) = t1_recv.recv().unwrap() {
let _result : &Vec<&i32> = &*t1_dat.read().unwrap();
t1_local.send(()).unwrap(); }
println!("Thread1 is done");
});
let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
let t2_dat = Arc::clone(&result_sync);
let t2_local = main_send.clone();
thread::spawn(move || {
while let Some(_) = t2_recv.recv().unwrap() {
let _result : &Vec<&i32> = &*t2_dat.read().unwrap();
t2_local.send(()).unwrap(); }
println!("Thread2 is done");
});
thread::spawn(move || {
start_combination_process(data, result_sync, k, vec![t1_send, t2_send], main_recv);
}).join().unwrap();
}
#[allow(non_snake_case)]
#[test]
fn test_share_result_CombinationIterator_with_thread_fn() {
let k = 3;
let data : &[i32] = &[1, 2, 3, 4, 5];
let (t1_send, t1_recv) = mpsc::sync_channel::<Option<Vec<&i32>>>(0);
thread::spawn(move || {
while let Some(c) = t1_recv.recv().unwrap() {
let _result : Vec<&i32> = c;
}
println!("Thread1 is done");
});
let (t2_send, t2_recv) = mpsc::sync_channel::<Option<Vec<&i32>>>(0);
thread::spawn(move || {
while let Some(c) = t2_recv.recv().unwrap() {
let _result : Vec<&i32> = c;
}
println!("Thread2 is done");
});
let channels = vec![t1_send, t2_send];
thread::spawn(move || {
use std::time::Instant;
let timer = Instant::now();
let mut counter = 0;
data.combination(k).for_each(|c| {
channels.iter().for_each(|t| {t.send(Some(c.to_owned())).unwrap();});
counter += 1;
});
channels.iter().for_each(|t| {t.send(None).unwrap()});
println!("Done {} combinations in {:?}", counter, timer.elapsed());
}).join().unwrap();
}
#[test]
fn test_shared_combination_result_iterator_alike() {
use std::fmt::Debug;
use std::time::Instant;
trait Consumer {
fn consume(&self);
}
struct Worker1<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
fn consume(&self) {
let result = self.data.borrow();
result.iter().for_each(|_| {});
}
}
struct Worker2<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
fn consume(&self) {
let result = self.data.borrow();
result.iter().for_each(|_| {});
}
}
let k = 4;
let data = &[1, 2, 3, 4, 5, 6, 7];
let mut result = vec![&data[0]; k];
let result_cell = Rc::new(RefCell::new(result.as_mut_slice()));
let worker1 = Worker1 {
data : Rc::clone(&result_cell)
};
let worker2 = Worker2 {
data : Rc::clone(&result_cell)
};
let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
let gosper = GosperCombinationCellIter::new(data, k, result_cell);
let timer = Instant::now();
let mut counter = 0;
for _ in gosper {
consumers.iter().for_each(|c| {c.consume()});
counter += 1;
}
println!("Total {} combinations done in {:?}", counter, timer.elapsed());
}
#[test]
fn test_unsafe_cartesian_product_shared_result() {
use std::fmt::Debug;
trait Consumer {
fn consume(&self);
}
struct Worker1<'a, T : 'a> {
data : &'a[&'a T]
}
impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
fn consume(&self) {
println!("Work1 has {:?}", self.data);
}
}
struct Worker2<'a, T : 'a> {
data : &'a[&'a T]
}
impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
fn consume(&self) {
println!("Work2 has {:?}", self.data);
}
}
unsafe fn start_cartesian_product_process<'a>(data : &'a[&'a[i32]], cur_result : *mut [&'a i32], consumers : Vec<Box<Consumer + 'a>>) {
unsafe_cartesian_product(data, cur_result, || {
consumers.iter().for_each(|c| {
c.consume();
})
});
}
let data : &[&[i32]] = &[&[1, 2], &[3, 4, 5], &[6]];
let mut result = vec![&data[0][0]; data.len()];
unsafe {
let shared = result.as_mut_slice() as *mut [&i32];
let worker1 = Worker1 {
data : &result
};
let worker2 = Worker2 {
data : &result
};
let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
start_cartesian_product_process(data, shared, consumers);
}
}
#[allow(unused)]
#[test]
fn test_unsafe_self_cartesian_product_shared_result() {
use std::fmt::Debug;
trait Consumer {
fn consume(&self);
}
struct Worker1<'a, T : 'a> {
data : &'a[&'a T]
}
impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
fn consume(&self) {
}
}
struct Worker2<'a, T : 'a> {
data : &'a[&'a T]
}
impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
fn consume(&self) {
}
}
unsafe fn start_cartesian_product_process<'a>(data : &'a[i32], n : usize, cur_result : *mut [&'a i32], consumers : Vec<Box<Consumer + 'a>>) {
use std::time::Instant;
let timer = Instant::now();
let mut counter = 0;
unsafe_self_cartesian_product(data, n, cur_result, || {
consumers.iter().for_each(|c| {
c.consume();
});
counter += 1;
});
println!("start_cartesian_product_process: {} products in {:?}", counter, timer.elapsed());
}
let data : &[i32] = &[1, 2, 3];
let n = 3;
let mut result = vec![&data[0]; n];
unsafe {
let shared = result.as_mut_slice() as *mut [&i32];
let worker1 = Worker1 {
data : &result
};
let worker2 = Worker2 {
data : &result
};
let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
start_cartesian_product_process(data, n, shared, consumers);
}
}
#[test]
fn test_cartesian_product_shared_result_fn() {
use std::fmt::Debug;
trait Consumer {
fn consume(&self);
}
struct Worker1<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
fn consume(&self) {
println!("Work1 has {:?}", self.data);
}
}
struct Worker2<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
fn consume(&self) {
println!("Work2 has {:?}", self.data);
}
}
fn start_cartesian_product_process<'a>(data : &'a[&'a[i32]], cur_result : Rc<RefCell<&'a mut [&'a i32]>>, consumers : Vec<Box<Consumer + 'a>>) {
cartesian_product_cell(data, cur_result, || {
consumers.iter().for_each(|c| {
c.consume();
})
});
}
let data : &[&[i32]] = &[&[1, 2], &[3, 4, 5], &[6]];
let mut result = vec![&data[0][0]; data.len()];
let shared = Rc::new(RefCell::new(result.as_mut_slice()));
let worker1 = Worker1 {
data : Rc::clone(&shared)
};
let worker2 = Worker2 {
data : Rc::clone(&shared)
};
let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
start_cartesian_product_process(data, shared, consumers);
}
#[allow(unused)]
#[test]
fn test_self_cartesian_product_shared_result_fn() {
use std::fmt::Debug;
trait Consumer {
fn consume(&self);
}
struct Worker1<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
fn consume(&self) {
println!("Work1 has {:?}", self.data);
}
}
struct Worker2<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
fn consume(&self) {
println!("Work2 has {:?}", self.data);
}
}
fn start_cartesian_product_process<'a>(data : &'a[i32], n : usize, cur_result : Rc<RefCell<&'a mut [&'a i32]>>, consumers : Vec<Box<Consumer + 'a>>) {
self_cartesian_product_cell(data, n, cur_result, || {
consumers.iter().for_each(|c| {
c.consume();
})
});
}
let data : &[i32] = &[1, 2, 3];
let n = 3;
let mut result = vec![&data[0]; n];
let shared = Rc::new(RefCell::new(result.as_mut_slice()));
let worker1 = Worker1 {
data : Rc::clone(&shared)
};
let worker2 = Worker2 {
data : Rc::clone(&shared)
};
let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
start_cartesian_product_process(data, n, shared, consumers);
}
#[allow(non_snake_case)]
#[test]
fn test_CartesianProduct_iterator_alike_shared_result() {
use std::fmt::Debug;
trait Consumer {
fn consume(&self);
}
struct Worker1<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
fn consume(&self) {
println!("Work1 has {:?}", self.data);
}
}
struct Worker2<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
fn consume(&self) {
println!("Work2 has {:?}", self.data);
}
}
fn start_cartesian_product_process<'a>(data : &'a[&'a[i32]], cur_result : Rc<RefCell<&'a mut [&'a i32]>>, consumers : Vec<Box<Consumer + 'a>>) {
let cart = CartesianProductCellIter::new(data, cur_result);
for _ in cart {
consumers.iter().for_each(|c| {
c.consume();
})
};
}
let data : &[&[i32]] = &[&[1, 2], &[3, 4, 5], &[6]];
let mut result = vec![&data[0][0]; data.len()];
let shared = Rc::new(RefCell::new(result.as_mut_slice()));
let worker1 = Worker1 {
data : Rc::clone(&shared)
};
let worker2 = Worker2 {
data : Rc::clone(&shared)
};
let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
start_cartesian_product_process(data, shared, consumers);
}
#[test]
fn test_shared_cartesian_product_result_sync_fn() {
fn start_cartesian_product_process<'a>(data : &'a[&[i32]], cur_result : Arc<RwLock<Vec<&'a i32>>>, notifier : Vec<SyncSender<Option<()>>>, release_recv : Receiver<()>) {
use std::time::Instant;
let timer = Instant::now();
let mut counter = 0;
cartesian_product_sync(data, cur_result, || {
notifier.iter().for_each(|n| {
n.send(Some(())).unwrap(); });
for _ in 0..notifier.len() {
release_recv.recv().unwrap(); }
counter += 1;
});
notifier.iter().for_each(|n| {n.send(None).unwrap()});
println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
}
let k = 3;
let data : &[&[i32]]= &[&[1, 2, 3], &[4, 5], &[6, 7, 8, 9, 10]];
let result = vec![&data[0][0]; k];
let result_sync = Arc::new(RwLock::new(result));
let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
let (main_send, main_recv) = mpsc::sync_channel(0);
let t1_local = main_send.clone();
let t1_dat = Arc::clone(&result_sync);
thread::spawn(move || {
while let Some(_) = t1_recv.recv().unwrap() {
let _result : &Vec<&i32> = &*t1_dat.read().unwrap();
t1_local.send(()).unwrap(); }
println!("Thread1 is done");
});
let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
let t2_dat = Arc::clone(&result_sync);
let t2_local = main_send.clone();
thread::spawn(move || {
while let Some(_) = t2_recv.recv().unwrap() {
let _result : &Vec<&i32> = &*t2_dat.read().unwrap();
t2_local.send(()).unwrap(); }
println!("Thread2 is done");
});
thread::spawn(move || {
start_cartesian_product_process(data, result_sync, vec![t1_send, t2_send], main_recv);
}).join().unwrap();
}
#[allow(non_snake_case)]
#[test]
fn test_shared_CartesianProduct_result_sync() {
let data : &[&[i32]]= &[&[1, 2, 3], &[4, 5], &[6, 7, 8, 9]];
let result = vec![&data[0][0]; data.len()];
let result_sync = Arc::new(RwLock::new(result));
let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
let t1_dat = Arc::clone(&result_sync);
thread::spawn(move || {
while let Some(_) = t1_recv.recv().unwrap() {
let _result : &Vec<&i32> = &*t1_dat.read().unwrap();
println!("Thread1: {:?}", _result);
}
println!("Thread1 is done");
});
let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
let t2_dat = Arc::clone(&result_sync);
thread::spawn(move || {
while let Some(_) = t2_recv.recv().unwrap() {
let _result : &Vec<&i32> = &*t2_dat.read().unwrap();
println!("Thread2: {:?}", _result);
}
println!("Thread2 is done");
});
let consumers = vec![t1_send, t2_send];
thread::spawn(move || {
use std::time::Instant;
let cart = CartesianProductIterator::new(data);
let mut counter = 0;
let timer = Instant::now();
cart.into_iter().for_each(|_| {
consumers.iter().for_each(|c| {
c.send(Some(())).unwrap();
});
counter += 1;
});
consumers.iter().for_each(|c| {
c.send(None).unwrap(); });
println!("Done {} products in {:?}", counter, timer.elapsed());
}).join().unwrap();
}
#[allow(non_snake_case)]
#[test]
fn test_share_CartesianProductIterator_result_to_thread() {
let data : &[&[i32]]= &[&[1, 2, 3], &[4, 5], &[6, 7, 8, 9]];
let (t1_send, t1_recv) = mpsc::channel::<Option<Vec<&i32>>>();
thread::spawn(move || {
while let Some(p) = t1_recv.recv().unwrap() {
println!("Thread1: {:?}", p);
}
println!("Thread1 is done");
});
let (t2_send, t2_recv) = mpsc::channel::<Option<Vec<&i32>>>();
thread::spawn(move || {
while let Some(p) = t2_recv.recv().unwrap() {
println!("Thread2: {:?}", p);
}
println!("Thread2 is done");
});
let consumers = vec![t1_send, t2_send];
thread::spawn(move || {
use std::time::Instant;
let cart = CartesianProductIterator::new(data);
let mut counter = 0;
let timer = Instant::now();
cart.into_iter().for_each(|p| {
println!("{:?}", p);
consumers.iter().for_each(|c| {
c.send(Some(p.to_owned())).unwrap();
});
counter += 1;
});
consumers.iter().for_each(|c| {
c.send(None).unwrap(); });
println!("Main: Done {} products in {:?}", counter, timer.elapsed());
}).join().unwrap();
}
#[test]
fn test_unsafe_shared_k_permutation_result_fn() {
use std::fmt::Debug;
trait Consumer {
fn consume(&self);
}
struct Worker1<'a, T : 'a> {
data : &'a[&'a T]
}
impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
fn consume(&self) {
println!("Work1 has {:?}", self.data);
}
}
struct Worker2<'a, T : 'a> {
data : &'a[&'a T]
}
impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
fn consume(&self) {
println!("Work2 has {:?}", self.data);
}
}
unsafe fn start_k_permutation_process<'a>(data : &'a[i32], cur_result : *mut [&'a i32], k : usize, consumers : Vec<Box<Consumer + 'a>>) {
unsafe_k_permutation(data, k, cur_result, || {
consumers.iter().for_each(|c| {
c.consume();
})
});
}
let k = 3;
let data = &[1, 2, 3, 4, 5];
let mut result = vec![&data[0]; k];
unsafe {
let shared = result.as_mut_slice() as *mut [&i32];
let worker1 = Worker1 {
data : &result
};
let worker2 = Worker2 {
data : &result
};
let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
start_k_permutation_process(data, shared, k, consumers);
}
}
#[test]
fn test_shared_k_permutation_result_fn() {
use std::fmt::Debug;
trait Consumer {
fn consume(&self);
}
struct Worker1<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
fn consume(&self) {
println!("Work1 has {:?}", self.data.borrow());
}
}
struct Worker2<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
fn consume(&self) {
println!("Work2 has {:?}", self.data.borrow());
}
}
fn start_k_permutation_process<'a>(data : &'a[i32], cur_result : Rc<RefCell<&'a mut [&'a i32]>>, k : usize, consumers : Vec<Box<Consumer + 'a>>) {
use std::time::Instant;
let timer = Instant::now();
let mut counter = 0;
k_permutation_cell(data, k, cur_result, || {
consumers.iter().for_each(|c| {
c.consume();
});
counter += 1;
});
println!("Total {} permutation done in {:?}", counter, timer.elapsed());
}
let k = 3;
let data = &[1, 2, 3, 4, 5];
let mut result = vec![&data[0]; k];
let shared = Rc::new(RefCell::new(result.as_mut_slice()));
let worker1 = Worker1 {
data : Rc::clone(&shared)
};
let worker2 = Worker2 {
data : Rc::clone(&shared)
};
let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
start_k_permutation_process(data, shared, k, consumers);
}
#[allow(non_snake_case)]
#[test]
fn test_shared_KPermutation_result() {
use std::time::Instant;
use std::fmt::Debug;
trait Consumer {
fn consume(&self);
}
struct Worker1<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
fn consume(&self) {
println!("Work1 has {:?}", self.data.borrow());
}
}
struct Worker2<'a, T : 'a> {
data : Rc<RefCell<&'a mut[&'a T]>>
}
impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
fn consume(&self) {
println!("Work2 has {:?}", self.data.borrow());
}
}
let k = 3;
let data = &[1, 2, 3, 4, 5];
let mut result = vec![&data[0]; k];
let shared = Rc::new(RefCell::new(result.as_mut_slice()));
let worker1 = Worker1 {
data : Rc::clone(&shared)
};
let worker2 = Worker2 {
data : Rc::clone(&shared)
};
let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
let kperm = KPermutationCellIter::new(data, k, shared);
let timer = Instant::now();
let mut counter = 0;
for _ in kperm {
consumers.iter().for_each(|c| {c.consume();});
counter += 1;
}
println!("Total {} permutation done in {:?}", counter, timer.elapsed());
assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
}
#[test]
fn test_shared_k_permutation_sync_fn() {
fn start_k_permutation_process<'a>(data : &'a[i32], cur_result : Arc<RwLock<Vec<&'a i32>>>, k : usize, notifier : Vec<SyncSender<Option<()>>>, release_recv : Receiver<()>) {
use std::time::Instant;
let timer = Instant::now();
let mut counter = 0;
k_permutation_sync(data, k, cur_result, || {
notifier.iter().for_each(|n| {
n.send(Some(())).unwrap(); });
for _ in 0..notifier.len() {
release_recv.recv().unwrap(); }
counter += 1;
});
notifier.iter().for_each(|n| {n.send(None).unwrap()});
println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
}
let k = 4;
let data = &[1, 2, 3, 4, 5, 6];
let result = vec![&data[0]; k];
let result_sync = Arc::new(RwLock::new(result));
let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
let (main_send, main_recv) = mpsc::sync_channel(0);
let t1_local = main_send.clone();
let t1_dat = Arc::clone(&result_sync);
thread::spawn(move || {
while let Some(_) = t1_recv.recv().unwrap() {
let _result : &Vec<&i32> = &*t1_dat.read().unwrap();
t1_local.send(()).unwrap(); }
println!("Thread1 is done");
});
let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
let t2_dat = Arc::clone(&result_sync);
let t2_local = main_send.clone();
thread::spawn(move || {
while let Some(_) = t2_recv.recv().unwrap() {
let _result : &Vec<&i32> = &*t2_dat.read().unwrap();
t2_local.send(()).unwrap(); }
println!("Thread2 is done");
});
thread::spawn(move || {
start_k_permutation_process(data, result_sync, k, vec![t1_send, t2_send], main_recv);
}).join().unwrap();
}
#[allow(non_snake_case)]
#[test]
fn test_share_result_KPermutation_iterator_sync() {
let k = 3;
let data : &[i32] = &[1, 2, 3, 4, 5];
let (t1_send, t1_recv) = mpsc::sync_channel::<Option<Vec<&i32>>>(0);
thread::spawn(move || {
while let Some(c) = t1_recv.recv().unwrap() {
let _result : Vec<&i32> = c;
println!("Thread1: {:?}", _result);
}
println!("Thread1 is done");
});
let (t2_send, t2_recv) = mpsc::sync_channel::<Option<Vec<&i32>>>(0);
thread::spawn(move || {
while let Some(c) = t2_recv.recv().unwrap() {
let _result : Vec<&i32> = c;
println!("Thread2: {:?}", _result);
}
println!("Thread2 is done");
});
let channels = vec![t1_send, t2_send];
thread::spawn(move || {
use std::time::Instant;
let timer = Instant::now();
let mut counter = 0;
let kperm = KPermutationIterator::new(data, k);
kperm.into_iter().for_each(|c| {
channels.iter().for_each(|t| {t.send(Some(c.to_owned())).unwrap();});
counter += 1;
});
channels.iter().for_each(|t| {t.send(None).unwrap()});
println!("Done {} combinations in {:?}", counter, timer.elapsed());
assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
}).join().unwrap();
}
#[test]
fn test_unsafe_cartesian_product() {
use std::time::Instant;
let set = (1..4).map(|item| item).collect::<Vec<u64>>();
let mut data = Vec::<&[u64]>::new();
for _ in 0..3 {
data.push(&set);
}
let mut counter = 0;
let mut result = vec![&data[0][0]; data.len()];
let result_ptr = result.as_mut_slice() as *mut [&u64];
let timer = Instant::now();
unsafe {
unsafe_cartesian_product(&data, result_ptr, || {
counter += 1;
});
}
println!("Total {} product done in {:?}", counter, timer.elapsed());
}
#[allow(unused)]
#[test]
fn test_unsafe_k_permutation() {
use std::time::{Instant};
let data = [1, 2, 3, 4, 5];
let k = 3;
let mut counter = 0;
let mut result = vec![&data[0]; k];
let timer = Instant::now();
unsafe {
unsafe_k_permutation(&data, k, result.as_mut_slice() as *mut [&usize], || {
counter += 1;
});
}
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
}
#[test]
fn test_tldr_case() {
let domains : &[&[i32]] = &[&[1, 2], &[3, 4, 5], &[6], &[7, 8], &[9, 10, 11]];
domains.cart_prod().for_each(|cp| {
cp.combination(3).for_each(|mut c| { println!("{:?}", c);
c.permutation().for_each(|p| {
println!("{:?}", p);
});
println!("{:?}", c);
})
});
}
#[test]
#[ignore]
fn compare_gosper_custom_fn() {
use std::time::Instant;
let data : Vec<i32> = (0..30i32).map(|i| {i}).collect();
let r = 20;
let mut counter = 0;
let timer = Instant::now();
combination(&data, r, |_c| {counter += 1});
println!("Stanford comb {} combination done in {:?}", counter, timer.elapsed());
counter = 0;
let timer = Instant::now();
large_combination(&data, r, |_c| {counter += 1});
println!("Custom comb {} combination done in {:?}", counter, timer.elapsed());
}
#[test]
#[ignore]
fn compare_gosper_custom_iter() {
use std::time::Instant;
let data : Vec<i32> = (0..30i32).map(|i| {i}).collect();
let r = 20;
let mut counter = 0;
let timer = Instant::now();
let stanford = GosperCombinationIterator::new(&data, r);
stanford.into_iter().for_each(|_c| {counter += 1});
println!("Stanford comb {} combination done in {:?}", counter, timer.elapsed());
counter = 0;
let timer = Instant::now();
let mut lc = LargeCombinationIterator::new(&data, r);
lc.iter().for_each(|_c| {counter += 1});
println!("Custom comb {} combination done in {:?}", counter, timer.elapsed());
}
#[test]
#[ignore]
fn compare_gosper_custom_cell_iter() {
use std::time::Instant;
let data : Vec<i32> = (0..30i32).map(|i| {i}).collect();
let r = 20;
let mut result = vec![&data[0]; r];
let share : Rc<RefCell<&mut[&i32]>> = Rc::new(RefCell::new(&mut result));
let mut counter = 0;
let timer = Instant::now();
let stanford = GosperCombinationCellIter::new(&data, r, Rc::clone(&share));
stanford.into_iter().for_each(|_c| {counter += 1});
println!("Stanford comb {} combination done in {:?}", counter, timer.elapsed());
counter = 0;
let timer = Instant::now();
let mut lc = LargeCombinationCellIter::new(&data, r, Rc::clone(&share));
lc.iter().for_each(|_c| {counter += 1});
println!("Custom comb {} combination done in {:?}", counter, timer.elapsed());
}
#[test]
#[ignore]
fn compare_gosper_custom_ref_iter() {
use std::time::Instant;
let data : Vec<i32> = (0..30i32).map(|i| {i}).collect();
let r = 20;
let mut result = vec![&data[0]; r];
let share = result.as_mut_slice() as *mut [&i32];
unsafe {
let mut counter = 0;
let timer = Instant::now();
let stanford = GosperCombinationRefIter::new(&data, r, share);
stanford.into_iter().for_each(|_c| {counter += 1});
println!("Stanford comb {} combination done in {:?}", counter, timer.elapsed());
counter = 0;
let timer = Instant::now();
let mut lc = LargeCombinationRefIter::new(&data, r, share);
lc.iter().for_each(|_c| {counter += 1});
println!("Custom comb {} combination done in {:?}", counter, timer.elapsed());
}
}
#[test]
#[ignore]
fn bench_heap_fn() {
use std::time::Instant;
let mut data : Vec<i32> = (0..10i32).map(|i| {i}).collect();
let timer = Instant::now();
let mut counter = 0;
heap_permutation(data.as_mut_slice(), |_p| {counter += 1});
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
}
#[test]
#[ignore]
fn bench_heap_iter() {
use std::time::Instant;
let mut data : Vec<i32> = (0..10i32).map(|i| {i}).collect();
let timer = Instant::now();
let mut counter = 0;
data.permutation().for_each(|_p| {counter += 1});
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
}
#[test]
#[ignore]
fn bench_k_perm_fn() {
use std::time::Instant;
let data : Vec<i32> = (0..13i32).map(|i| {i}).collect();
let timer = Instant::now();
let mut counter = 0;
k_permutation(data.as_slice(), 7, |_p| {counter += 1});
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
}
#[test]
#[ignore]
fn bench_k_perm_iter() {
use std::time::Instant;
let data : Vec<i32> = (0..13i32).map(|i| {i}).collect();
let timer = Instant::now();
let mut counter = 0;
(data.as_slice(), 7usize).permutation().for_each(|_p| {counter += 1});
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
}
#[test]
#[ignore]
fn bench_cart_fn() {
use std::time::Instant;
let domain : Vec<i32> = (0..5i32).map(|i| {i}).collect();
let domains : Vec<&[i32]> = (0..10).map(|_| domain.as_slice()).collect();
let timer = Instant::now();
let mut counter = 0;
cartesian_product(domains.as_slice(), |_p| {counter += 1});
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
}
#[test]
#[ignore]
fn bench_cart_iter() {
use std::time::Instant;
let domain : Vec<i32> = (0..5i32).map(|i| {i}).collect();
let domains : Vec<&[i32]> = (0..10).map(|_| domain.as_slice()).collect();
let timer = Instant::now();
let mut counter = 0;
domains.as_slice().cart_prod().for_each(|_p| {counter += 1});
println!("Total {} permutations done in {:?}", counter, timer.elapsed());
}
}