Fixed combination and renamed digits to more generic elements in permutation, big sets still not working

This commit is contained in:
Fabian Schmidt 2024-11-28 13:34:22 +01:00
parent e293fb90d3
commit 87b4b49dad
2 changed files with 85 additions and 85 deletions

View File

@ -53,7 +53,7 @@ pub fn nth_lex<T: Clone + Ord>(
#[derive(Clone)] #[derive(Clone)]
pub struct Combinator<T: Clone + Ord> { pub struct Combinator<T: Clone + Ord> {
pub current: Vec<T>, pub elements: Vec<T>,
pub k: usize, pub k: usize,
idx: usize, idx: usize,
} }
@ -64,7 +64,7 @@ impl<T: Clone + Ord> Combinator<T> {
return Err(Box::from("Out of bounds")); return Err(Box::from("Out of bounds"));
} }
Ok(Self { Ok(Self {
current: elements, elements,
k, k,
idx: 0, idx: 0,
}) })
@ -75,7 +75,7 @@ impl<T: Clone + Ord> Iterator for Combinator<T> {
type Item = Vec<T>; type Item = Vec<T>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let num_elements = self.current.len(); let num_elements = self.elements.len();
let num_combinations = binomial(num_elements, self.k); let num_combinations = binomial(num_elements, self.k);
if self.idx == num_combinations { if self.idx == num_combinations {
return None; return None;
@ -83,7 +83,7 @@ impl<T: Clone + Ord> Iterator for Combinator<T> {
let mut i = 0; let mut i = 0;
let mut remaining_k = self.k; let mut remaining_k = self.k;
let mut comb = Vec::new(); let mut comb = Vec::new();
let mut remainder = self.idx - 1; let mut remainder = self.idx;
while remaining_k > 0 { while remaining_k > 0 {
// Count the number of combinations that start with elements[i] // Count the number of combinations that start with elements[i]
// example with n = 5, k = 2 // example with n = 5, k = 2
@ -94,7 +94,7 @@ impl<T: Clone + Ord> Iterator for Combinator<T> {
let count = binomial(num_elements - i - 1, remaining_k - 1); let count = binomial(num_elements - i - 1, remaining_k - 1);
if remainder < count { if remainder < count {
// If the nth combination is within the count, pick this element // If the nth combination is within the count, pick this element
comb.push(self.current[i].clone()); comb.push(self.elements[i].clone());
remaining_k -= 1; remaining_k -= 1;
} else { } else {
remainder -= count; remainder -= count;
@ -102,14 +102,13 @@ impl<T: Clone + Ord> Iterator for Combinator<T> {
i += 1; i += 1;
} }
self.idx += 1; self.idx += 1;
self.current = comb; Some(comb)
Some(self.current.clone())
} }
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::combination::nth_lex; use crate::combination::{nth_lex, Combinator};
const SMALL: [i8; 5] = [1, 2, 3, 4, 5]; const SMALL: [i8; 5] = [1, 2, 3, 4, 5];
@ -161,84 +160,85 @@ mod test {
assert!(nth_lex(small, 1, 6).is_err()); assert!(nth_lex(small, 1, 6).is_err());
} }
// Can't yet use too big values
//#[test]
//fn nth_lex_all_big() {
// let big: Vec<i32> = (0..100).collect();
// assert_eq!(
// nth_lex(big.clone(), 100, 1).unwrap(),
// (0..100).collect::<Vec<i32>>()
// );
// assert!(nth_lex(big, 100, 2).is_err());
//}
//#[test]
//fn nth_lex_some_big() {
// let big: Vec<i32> = (0..100).collect();
// assert_eq!(
// nth_lex(big.clone(), 50, 1).unwrap(),
// (0..50).collect::<Vec<i32>>()
// );
//}
//#[test]
//fn nth_lex_one_big() {
// let big: Vec<i32> = (0..100).collect();
// assert_eq!(nth_lex(big.clone(), 1, 1).unwrap(), vec![0]);
// assert_eq!(nth_lex(big.clone(), 1, 2).unwrap(), vec![1]);
// assert_eq!(nth_lex(big.clone(), 1, 3).unwrap(), vec![2]);
// assert_eq!(nth_lex(big.clone(), 1, 4).unwrap(), vec![3]);
//}
// Combinator
#[test] #[test]
fn nth_lex_all_big() { fn comb_zero_small() {
let big: Vec<i32> = (0..100).collect(); let small = SMALL.to_vec();
assert_eq!( let comb = Combinator::new(small, 0);
nth_lex(big.clone(), 100, 1).unwrap(), assert!(comb.is_err());
(0..100).collect::<Vec<i32>>()
);
assert!(nth_lex(big, 100, 2).is_err());
} }
#[test] #[test]
fn nth_lex_some_big() { fn comb_more_small() {
let big: Vec<i32> = (0..100).collect(); let small = SMALL.to_vec();
assert_eq!( let comb = Combinator::new(small, 6);
nth_lex(big.clone(), 50, 1).unwrap(), assert!(comb.is_err());
(0..50).collect::<Vec<i32>>()
);
} }
#[test] #[test]
fn nth_lex_one_big() { fn comb_all_small() {
let big: Vec<i32> = (0..100).collect(); let small = SMALL.to_vec();
assert_eq!(nth_lex(big.clone(), 1, 1).unwrap(), vec![0]); let mut comb = Combinator::new(small, 5).unwrap();
assert_eq!(nth_lex(big.clone(), 1, 2).unwrap(), vec![1]); assert!(comb.next() == Some(vec![1, 2, 3, 4, 5]));
assert_eq!(nth_lex(big.clone(), 1, 3).unwrap(), vec![2]); assert!(comb.next().is_none());
assert_eq!(nth_lex(big.clone(), 1, 4).unwrap(), vec![3]);
} }
// Combinator. Needs fixing #[test]
fn comb_some_small() {
//#[test] let small = SMALL.to_vec();
//fn comb_zero_small() { let mut comb = Combinator::new(small, 2).unwrap();
// let small = SMALL.to_vec(); assert_eq!(comb.next(), Some(vec![1, 2]));
// let comb = Combinator::new(small, 0); assert_eq!(comb.next(), Some(vec![1, 3]));
// assert!(comb.is_err()); assert_eq!(comb.next(), Some(vec![1, 4]));
//} assert_eq!(comb.next(), Some(vec![1, 5]));
assert_eq!(comb.next(), Some(vec![2, 3]));
//#[test] assert_eq!(comb.next(), Some(vec![2, 4]));
//fn comb_more_small() { assert_eq!(comb.next(), Some(vec![2, 5]));
// let small = SMALL.to_vec(); assert_eq!(comb.next(), Some(vec![3, 4]));
// let comb = Combinator::new(small, 6); assert_eq!(comb.next(), Some(vec![3, 5]));
// assert!(comb.is_err()); assert_eq!(comb.next(), Some(vec![4, 5]));
//} assert!(comb.next().is_none());
}
//#[test]
//fn comb_all_small() { #[test]
// let small = SMALL.to_vec(); fn comb_one_small() {
// let mut comb = Combinator::new(small, 5).unwrap(); let small = SMALL.to_vec();
// assert!(comb.next() == Some(vec![1, 2, 3, 4, 5])); let mut comb = Combinator::new(small, 1).unwrap();
// assert!(comb.next().is_none()); assert_eq!(comb.next(), Some(vec![1]));
//} assert_eq!(comb.next(), Some(vec![2]));
assert_eq!(comb.next(), Some(vec![3]));
//#[test] assert_eq!(comb.next(), Some(vec![4]));
//fn comb_some_small() { assert_eq!(comb.next(), Some(vec![5]));
// let small = SMALL.to_vec(); assert!(comb.next().is_none());
// let mut comb = Combinator::new(small, 2).unwrap(); }
// assert_eq!(comb.next(), Some(vec![1, 2]));
// assert_eq!(comb.next(), Some(vec![1, 3]));
// assert_eq!(comb.next(), Some(vec![1, 4]));
// assert_eq!(comb.next(), Some(vec![1, 5]));
// assert_eq!(comb.next(), Some(vec![2, 3]));
// assert_eq!(comb.next(), Some(vec![2, 4]));
// assert_eq!(comb.next(), Some(vec![2, 5]));
// assert_eq!(comb.next(), Some(vec![3, 4]));
// assert_eq!(comb.next(), Some(vec![3, 5]));
// assert_eq!(comb.next(), Some(vec![4, 5]));
// assert!(comb.next().is_none());
//}
//#[test]
//fn comb_one_small() {
// let small = SMALL.to_vec();
// let mut comb = Combinator::new(small, 1).unwrap();
// assert_eq!(comb.next(), Some(vec![1]));
// assert_eq!(comb.next(), Some(vec![2]));
// assert_eq!(comb.next(), Some(vec![3]));
// assert_eq!(comb.next(), Some(vec![4]));
// assert_eq!(comb.next(), Some(vec![5]));
// assert!(comb.next().is_none());
//}
} }

View File

@ -64,17 +64,17 @@ impl<T: Clone + Ord + std::fmt::Display> Iterator for Permutator<T> {
self.idx += 1; self.idx += 1;
return Some(self.elements.clone()); return Some(self.elements.clone());
} }
let num_unique_digits = self.elements.len(); let num_unique_elements = self.elements.len();
if self.idx == factorial(num_unique_digits) { if self.idx == factorial(num_unique_elements) {
return None; return None;
} }
let mut digits = self.elements.clone(); let mut elements = self.elements.clone();
let mut perm = Vec::new(); let mut perm = Vec::new();
let mut remainder = self.idx; let mut remainder = self.idx;
for idx in 1..=num_unique_digits { for idx in 1..=num_unique_elements {
let permutations = remainder / factorial(num_unique_digits - idx); let permutations = remainder / factorial(num_unique_elements - idx);
remainder %= factorial(num_unique_digits - idx); remainder %= factorial(num_unique_elements - idx);
perm.push(digits.remove(permutations)); perm.push(elements.remove(permutations));
} }
self.idx += 1; self.idx += 1;
Some(perm) Some(perm)