Goal: Create a function that returns an iterator for all combinations according to nCr.
For example, let n = 5 and let c = 3
. The iterator should yield slices containing the following data.
0 1 20 1 30 1 40 2 30 2 40 3 41 2 31 2 41 3 4
To challenge myself, as I'm new to rust, I want to do it without allocating a new vector for every iteration. Instead, the iterator should modify a vector that it owns and always return a slice over the same vector. Yes, I know the values in the slice will change if the slice is improperly used after subsequent calls to next
on the iterator.
/// Usage: /// Let's find all factors of 100. We have obtained all the prime factors earlier./// ```/// let prime_factors = vec![2, 2, 5, 5]; // obtained earlier/// let mut all_factors = new HashMap::<usize>();/// all_factors.insert(1);////// // now use every combination of prime factors to find all the factors/// for c in 1..prime_factors.len() { /// for indexes in combinations(prime_factors.len(), c) {/// let factor = 1;/// for index in indexes { /// factor *= prime_factors[index];/// }/// all_factors.insert(factor);/// }/// }////// // all_factors now contains [1, 2, 4, 5, 10, 20, 50, 100]/// ````fn combinations<'a>(n: usize, c: usize) -> impl Iterator<Item = &'a [usize]> { struct State<'a> { n: usize, c: usize, indexes: Vec<usize>, // I think State should OWN this vector phantom: PhantomData<&'a ()>, // But I needed a field with a lifetime } impl<'a> State<'a> { fn new(n: usize, c: usize) -> State<'a> { State { n, c, indexes: (0..c).collect::<Vec<usize>>(), phantom: PhantomData, } } fn update(&mut self) -> bool { fn update(indexes: &mut Vec<usize>, at: usize, max: usize) -> bool { indexes[at] += 1; if indexes[at] == max { if at == 0 { return false; } if !update(indexes, at - 1, max - 1) { return false; } indexes[at] = indexes[at - 1] + 1; } true } update(&mut self.indexes, self.c - 1, self.c) } } impl<'a> Iterator for State<'a> { type Item = &'a [usize]; fn next(self: &mut State<'a>) -> Option<&'a [usize]> { if self.update() { Some(&self.indexes[..]) } else { None } } } State::new(n, c)}