Created
February 9, 2018 16:26
-
-
Save ioncodes/6573785e8570b017c9a64a4e85cf1ca0 to your computer and use it in GitHub Desktop.
Combination generator which does NOT work. This has a reference issue. This is just to show the difference between a good structure and a bad structure. For @mortoray. (Not that your structure is bad <3)
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>> | |
} | |
impl<T> Combinations<T> { | |
pub fn new() -> Combinations<T> { | |
Combinations { | |
combinations: Vec::<Vec<T>>::new() | |
} | |
} | |
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(); | |
} | |
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() | |
} | |
} | |
struct CombinationsIntoIterator<T> { | |
combinations: Combinations<T>, | |
index: usize, | |
} | |
impl<T> IntoIterator for Combinations<T> where T: std::clone::Clone { | |
type Item = Vec<T>; | |
type IntoIter = CombinationsIntoIterator<T>; | |
fn into_iter(self) -> Self::IntoIter { | |
CombinationsIntoIterator { combinations: self, index: 0 } | |
} | |
} | |
impl<T> Iterator for CombinationsIntoIterator<T> where T: std::clone::Clone { | |
type Item = Vec<T>; | |
fn next(&mut self) -> Option<Vec<T>> { | |
let c = self.combinations.combinations[self.index].to_vec(); | |
let result = c; | |
self.index += 1; | |
Some(result) | |
} | |
} | |
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 c.into_iter() { | |
println!("{:?}", c); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment