Created
November 17, 2015 07:28
-
-
Save kylewlacy/115965b40e02a3325558 to your computer and use it in GitHub Desktop.
Cartesian product function in Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Given a vector containing a partial Cartesian product, and a list of items, | |
/// return a vector adding the list of items to the partial Cartesian product. | |
/// | |
/// # Example | |
/// | |
/// ``` | |
/// let partial_product = vec![vec![1, 4], vec![1, 5], vec![2, 4], vec![2, 5]]; | |
/// let items = &[6, 7]; | |
/// let next_product = partial_cartesian(partial_product, items); | |
/// assert_eq!(next_product, vec![vec![1, 4, 6], | |
/// vec![1, 4, 7], | |
/// vec![1, 5, 6], | |
/// vec![1, 5, 7], | |
/// vec![2, 4, 6], | |
/// vec![2, 4, 7], | |
/// vec![2, 5, 6], | |
/// vec![2, 5, 7]]); | |
/// ``` | |
pub fn partial_cartesian<T: Clone>(a: Vec<Vec<T>>, b: &[T]) -> Vec<Vec<T>> { | |
a.into_iter().flat_map(|xs| { | |
b.iter().cloned().map(|y| { | |
let mut vec = xs.clone(); | |
vec.push(y); | |
vec | |
}).collect::<Vec<_>>() | |
}).collect() | |
} | |
/// Computes the Cartesian product of lists[0] * lists[1] * ... * lists[n]. | |
/// | |
/// # Example | |
/// | |
/// ``` | |
/// let lists: &[&[_]] = &[&[1, 2], &[4, 5], &[6, 7]]; | |
/// let product = cartesian_product(lists); | |
/// assert_eq!(product, vec![vec![1, 4, 6], | |
/// vec![1, 4, 7], | |
/// vec![1, 5, 6], | |
/// vec![1, 5, 7], | |
/// vec![2, 4, 6], | |
/// vec![2, 4, 7], | |
/// vec![2, 5, 6], | |
/// vec![2, 5, 7]]); | |
/// ``` | |
pub fn cartesian_product<T: Clone>(lists: &[&[T]]) -> Vec<Vec<T>> { | |
match lists.split_first() { | |
Some((first, rest)) => { | |
let init: Vec<Vec<T>> = first.iter().cloned().map(|n| vec![n]).collect(); | |
rest.iter().cloned().fold(init, |vec, list| { | |
partial_cartesian(vec, list) | |
}) | |
}, | |
None => { | |
vec![] | |
} | |
} | |
} | |
/// Print the Cartesian product of a set of lists to stdout, in | |
/// the following form: | |
/// | |
/// ```text | |
/// 1 4 6 | |
/// 1 4 7 | |
/// 1 5 6 | |
/// 1 5 7 | |
/// 2 4 6 | |
/// 2 4 7 | |
/// ... | |
/// ``` | |
pub fn print_cartesian_product(lists: &[&[i32]]) { | |
let products = cartesian_product(lists); | |
for product in products.iter() { | |
let product_str: Vec<_> = product.iter().map(|n| format!("{}", n)).collect(); | |
let line = product_str.join(" "); | |
println!("{}", line); | |
} | |
} | |
fn main() { | |
let a = &[1, 2, 3]; | |
let b = &[4, 5]; | |
let c = &[6, 7, 8]; | |
print_cartesian_product(&[a, b, c]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment