Skip to content

Instantly share code, notes, and snippets.

@ioncodes
Created February 9, 2018 16:26
Show Gist options
  • Save ioncodes/6573785e8570b017c9a64a4e85cf1ca0 to your computer and use it in GitHub Desktop.
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)
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