[go: up one dir, main page]

permutator 0.2.0

Get a lexicographic cartesian product and lexicographic permutation at any specific index from data. Generate complete lexicographic cartesian product from multiple set of data. Generate complete non-lexicographic combination from data. Generate non-lexicographic k-permutation.
Documentation

This crate provide generic cartesian product iterator, combination iterator, and permutation iterator.

Three main functionalities

  • Cartesian product
  • Combination
  • Permutation

Two different style on every functionality

This crate provide two implementation style

  • Iterator style
  • Callback function style

Easily share result

  • Every functionalities can take Rc<RefCell<>> to store result.
  • An iterator that return owned value.
  • Every callback style function can take Arc<RwLock<>> to store result.

Easy usage

Three built-in traits that add cart_prod, combination, and permutation functionality to slice/array, Rc<RefCell<&mut[T]>>, and more.

Unreach raw performance with unsafe

Every functionalities can take raw mutable pointer to store result.

Example

  • Getting k-permutation where k is 3 and n is 5.
use permutator::{Combination, Permutation};
let mut data = &[1, 2, 3, 4, 5];
let mut counter = 1;
data.combination(3).for_each(|mut c| {
c.permutation().for_each(|p| {
println!("k-permutation@{}={:?}", counter, p);
counter += 1;
});
});
  • Cartesian product of set of 3, 4, and 5 respectively
use permutator::{CartesianProductIterator, cartesian_product};
let mut domains : &[&[i32]]= &[&[1, 2], &[3, 4, 5], &[6, 7, 8, 9]];
println!("=== Cartesian product iterative style ===");
CartesianProductIterator::new(domains).into_iter().for_each(|p| {
println!("{:?}", p);
});
println!("=== cartesian product callback style ===");
cartesian_product(domains, |p| {
// `p` is borrowed a ref to internal variable inside cartesian_product function.
println!("{:?}", p);
});
  • Easy sharable result
use std::cell::RefCell;
use std::rc::Rc;
use std::time::Instant;
use permutator::CartesianProduct;

let mut counter = 0;
let timer = Instant::now();
let data : &[&[u8]]= &[&[1, 2], &[3, 4, 5, 6], &[7, 8, 9]];
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(|_| {
println!("{:?}", &*shared.borrow());
// and notify result borrower(s) that new product is available.

counter += 1;
});

println!("Total {} products done in {:?}", counter, timer.elapsed());
  • Unsafely share result example
use std::time::Instant;
use permutator::Permutation;

let data : &[i32] = &[1, 2, 3, 4, 5];
let mut counter = 0;
let k = 3;
let mut result : Vec<&i32> = vec![&data[0]; k];
// `result` can be share safely anywhere
let shared = result.as_mut_slice() as *mut [&i32];
// `shared` can be share as long as `result` is alive
let timer = Instant::now();
// unsafe statement may be omit because the permutation trait
// hid it internally. However, keep in mind that it rely
// on a pointer so every operation is still considered unsafe.
unsafe {
(data, k, shared).permutation().for_each(|_| {
println!("{:?}", &*shared);
// and notify result borrower(s) that new permutation is available.

counter += 1;
});

println!("Total {} combination done in {:?}", counter, timer.elapsed());
}

See