use std::error::Error; fn factorial(num: usize) -> usize { let mut fact = 1; for n in 1..=num { fact *= n; } fact } #[derive(Clone)] pub struct Permutator { pub current: Vec, idx: usize, } impl Permutator { pub fn new(elements: Vec) -> Self { Self { current: elements, idx: 0, } } /// Explanation /// /// there are 10! possible permutations /// for each first number there are 9!, for each first 2 numbers 8!, etc. /// we check how many times we have 9! permutations before we're over 1_000_000 /// aka. 1000000 / 9! /// we take the remainder and check how many times we have 8! before we?re over it /// (1000000 % 9!) 8! /// etc. /// every iteration we remove the digit by the idx from the original permutation /// we only check for 999999 permutations because we already have the first one /// pub fn nth_lex(mut digits: Vec, nth: usize) -> Result, Box> { digits.sort(); if nth == 1 { return Ok(digits); } if nth > factorial(digits.len()) || nth == 0 { return Err(Box::from("Out of bounds")); } let mut perm = Vec::new(); let num_unique_digits = digits.len(); let mut remainder = nth - 1; for idx in 1..=digits.len() { let permutations = remainder / factorial(num_unique_digits - idx); remainder %= factorial(num_unique_digits - idx); perm.push(digits[permutations]); digits.remove(permutations); } Ok(perm) } } impl Iterator for Permutator { type Item = Vec; /// Returns the next permutation and changes the current permutation to it /// This operation wraps around fn next(&mut self) -> Option { if self.current.is_empty() { return None; } let mut digits = self.current.clone(); if self.idx == factorial(digits.len()) { return None; } let mut perm = Vec::new(); let num_unique_digits = digits.len(); let mut remainder = 1; for idx in 1..=digits.len() { let permutations = remainder / factorial(num_unique_digits - idx); remainder %= factorial(num_unique_digits - idx); perm.push(digits[permutations]); digits.remove(permutations); } self.idx += 1; self.current = digits; Some(self.current.clone()) } }