Permutate vector values

Permutate vector values

There is my Rust Playground to an iterative and the looping variants of vector permutation in Rust language.
As known the iterative variant is a little bit faster.

#[allow(dead_code)]
type TItem = u8;
#[allow(dead_code)]
fn permutate_combinations(alternatives: &[&Vec<TItem>]) -> Vec<Vec<TItem>> {
if alternatives.len() <= 1 {
if alternatives.len() == 1 {
alternatives[0]
.iter()
.map(|alt| vec![*alt])
.collect::<Vec<Vec<TItem>>>()
} else {
return Vec::new();
}
} else {
let rest_rslt = permutate_combinations(&alternatives[1..]);
rest_rslt
.iter()
.fold(Vec::<Vec<TItem>>::new(), |mut acc, rslt| {
alternatives[0].iter().for_each(|alt| {
let mut v = vec![*alt];
v.append(&mut rslt.clone());
acc.push(v);
});
acc
})
}
}
#[allow(dead_code)]
fn permutate_combinations_loop(alternatives: &[&Vec<TItem>]) -> Vec<Vec<TItem>> {
if alternatives.len() <= 1 {
if alternatives.len() == 1 {
alternatives[0]
.iter()
.map(|alt| vec![*alt])
.collect::<Vec<Vec<TItem>>>()
} else {
return Vec::new();
}
} else {
let mut result = Vec::<Vec<TItem>>::new();
let rest_rslt = permutate_combinations(&alternatives[1..]);
for i in 0..rest_rslt.len() {
for alt in alternatives[0] {
let mut v = vec![*alt];
v.append(&mut rest_rslt[i].clone());
result.push(v);
}
}
result
}
}
#[cfg(test)]
mod tests {
use crate::{permutate_combinations, permutate_combinations_loop, TItem};
use std::time::Instant;
#[test]
fn test_permutate_combinations() {
let data = [vec![1u8, 2, 3], vec![4, 5], vec![9], vec![12, 13]];
let alternatives = data.iter().map(|d| d).collect::<Vec<&Vec<TItem>>>();
let before = Instant::now();
for _ in 0..5000 {
let _combinations = permutate_combinations(&alternatives);
}
println!("[permutate_combinations] Elapsed time: {:.2?}", before.elapsed());
let combinations = permutate_combinations(&alternatives);
assert_eq!(0, combinations.iter().filter(|&v| v.len() != 4).count());
for c in combinations[0..5].iter() {
let cnt = combinations.iter().filter(|&v| c == v).count();
assert_eq!(1, cnt);
}
assert_eq!(12, combinations.len());
}
#[test]
fn test_permutate_combinations_loop() {
let data = [vec![1u8, 2, 3], vec![4, 5], vec![9], vec![12, 13]];
let alternatives = data.iter().map(|d| d).collect::<Vec<&Vec<TItem>>>();
let before = Instant::now();
for _ in 0..5000 {
let _combinations = permutate_combinations_loop(&alternatives);
}
println!("[permutate_combinations_loop] Elapsed time: {:.2?}", before.elapsed());
let combinations = permutate_combinations_loop(&alternatives);
assert_eq!(0, combinations.iter().filter(|&v| v.len() != 4).count());
for c in combinations[0..5].iter() {
let cnt = combinations.iter().filter(|&v| c == v).count();
assert_eq!(1, cnt);
}
assert_eq!(12, combinations.len());
}
}
view raw playground.rs hosted with ❤ by GitHub