Last active
February 9, 2018 16:31
-
-
Save ioncodes/3401ebc8c71bd41638e483e96d2d40f1 to your computer and use it in GitHub Desktop.
Generic combinations generator in Rust with iterator. Created for @mortoray.
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
use std::ops::{Index, IndexMut}; | |
struct Combinations<T> { | |
combinations: Vec<Vec<T>>, | |
index: usize, | |
} | |
impl<T> Combinations<T> { | |
pub fn new() -> Combinations<T> { | |
Combinations { | |
combinations: Vec::<Vec<T>>::new(), | |
index: 0, | |
} | |
} | |
pub fn generate(&mut self, arr: &Vec<T>, len: usize, init_value: T) where T: std::clone::Clone { | |
self.combs(arr, len, 0, &mut vec![init_value; len]); | |
} | |
pub fn clear(&mut self) { | |
self.combinations.clear(); | |
self.index = 0; | |
} | |
pub fn len(&self) -> usize { | |
self.combinations.len() | |
} | |
fn combs(&mut self, arr: &Vec<T>, len: usize, pos: usize, result: &mut Vec<T>) where T: std::clone::Clone { | |
if len == 0 { | |
self.combinations.push(result.to_vec()); | |
return; | |
} | |
let res_len = result.len(); | |
let arr_len = arr.len(); | |
for i in pos..(arr_len - len + 1) { | |
let ref a = arr[i]; | |
result[res_len - len] = a.to_owned(); | |
self.combs(arr, len - 1, i + 1, result); | |
} | |
} | |
} | |
impl<T> Index<usize> for Combinations<T> { | |
type Output = Vec<T>; | |
fn index(&self, index: usize) -> &Vec<T> { | |
self.combinations.get(index).unwrap() | |
} | |
} | |
impl<T> IndexMut<usize> for Combinations<T> { | |
fn index_mut(&mut self, index: usize) -> &mut Vec<T> { | |
self.combinations.get_mut(index).unwrap() | |
} | |
} | |
impl<T> Iterator for Combinations<T> where T: std::clone::Clone { | |
type Item = Vec<T>; | |
fn next(&mut self) -> Option<Vec<T>> { | |
let c = self.combinations[self.index].to_vec(); | |
self.index += 1; | |
Some(c) | |
} | |
} | |
fn main() { | |
let v = &vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; | |
let c = &mut Combinations::<usize>::new(); | |
for i in 2..5 { // 2,3,4 | |
c.clear(); | |
c.generate(v, i, 0); | |
for j in 0..c.len() { | |
println!("{:?}", c[j]); | |
c.next(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment