Skip to content

Instantly share code, notes, and snippets.

@ericyd
Last active April 30, 2018 19:40
Show Gist options
  • Save ericyd/101ce779a6550a28a5c3e3109f0b84cb to your computer and use it in GitHub Desktop.
Save ericyd/101ce779a6550a28a5c3e3109f0b84cb to your computer and use it in GitHub Desktop.
Rust script to get all possible combinations of sets of vectors
// some experiments with combinations and deduping
// I think clippy has some good recommendations - I wrote this while learning Rust so it's rough
fn main() {
let arr = vec![vec![1, 1, 1], vec![2, 2, 2], vec![3, 3, 3], vec![4, 4, 4]];
let mut indices = arr.iter().map(|ref _x| 0).collect();
let mut paths: Vec<Vec<usize>> = vec![];
let paths = find_combinations(&arr, &mut indices, 0, &mut paths);
let paths_dedupe1 = dedupe(&paths, &mut vec![]);
let paths_dedupe2 = dedupe2(&paths);
assert_eq!(paths.len(), paths_dedupe1.len(), "dedupe 1 has different length than original");
assert_eq!(paths.len(), paths_dedupe2.len(), "dedupe 2 has different length than original");
// this is only true if they are all the same size
// e.g. {elements per array}^{number of arrays}
// else, would have to just multiply lengths of all elements in arr
assert_eq!(
paths.len(),
arr[0].len().pow(arr.len() as u32),
"paths contains wrong number of elements"
);
}
fn find_combinations<'a>(
arr: &Vec<Vec<i32>>,
indices: &mut Vec<usize>,
index: usize,
paths: &'a mut Vec<Vec<usize>>,
) -> &'a Vec<Vec<usize>> {
for (i, _) in arr[index].iter().enumerate() {
let i = i as usize;
indices[index] = i;
if index == arr.len() - 1 {
paths.push(indices.clone());
}
if index < arr.len() - 1 {
find_combinations(arr, indices, index + 1, paths);
}
}
paths
}
fn dedupe(arr: &Vec<Vec<usize>>, result: &mut Vec<Vec<usize>>) -> Vec<Vec<usize>> {
for (i, val) in arr.iter().enumerate() {
// if first item that matches this value is the value itself,
// it is not a duplicate. Otherwise, it is.
match arr.iter().position(|ref x| x == &val) {
Some(x) => {
if x == i {
result.push(val.clone());
}
}
None => (),
}
}
result.clone()
}
fn dedupe2(arr: &Vec<Vec<usize>>) -> Vec<Vec<usize>> {
arr.iter()
.enumerate()
.filter(|&(index, value)| match arr.iter().position(
|ref y| y == &value,
) {
Some(x) => {
if index == x {
return true;
}
return false;
}
None => return false,
})
.map(|(_index, value)| value.clone())
.collect()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment