From 5b5c77d5b48651c6a328c6708a1ea4b01540c4e6 Mon Sep 17 00:00:00 2001 From: timeshifter Date: Sun, 14 Aug 2022 18:43:40 +0200 Subject: [PATCH] fix combinations for 51 (WIP) --- euler51/src/combination.rs | 77 ++++++++++++++++++++++++++++++++++++++ euler51/src/main.rs | 8 ++-- euler51/src/permutation.rs | 75 ------------------------------------- 3 files changed, 81 insertions(+), 79 deletions(-) create mode 100644 euler51/src/combination.rs delete mode 100644 euler51/src/permutation.rs diff --git a/euler51/src/combination.rs b/euler51/src/combination.rs new file mode 100644 index 0000000..92c7935 --- /dev/null +++ b/euler51/src/combination.rs @@ -0,0 +1,77 @@ +struct PositionCombinations { + min_length: usize, + state: Vec, + finished: bool, +} + +impl Iterator for PositionCombinations { + type Item = Vec; + + fn next(&mut self) -> Option { + if self.finished { + return None; + } + loop { + let result = self.state.clone(); + self.increment(); + if result.iter().filter(|x| **x).count() >= self.min_length { + return Some(result); + } + } + } +} + +impl PositionCombinations { + fn new(min_length: usize, max_length: usize) -> Self { + let state = vec![false; max_length]; + let finished = false; + Self { + min_length, + state, + finished, + } + } + + fn increment(&mut self) { + let mut overflow = self.state[0]; + self.state[0] ^= true; + for position in self.state[1..].iter_mut() { + let new_overflow = *position & overflow; + *position ^= overflow; + overflow = new_overflow; + } + if overflow { + self.finished = true; + } + } +} + +#[cfg(test)] +mod test { + #[test] + fn test_combination() { + use crate::combination::PositionCombinations; + use std::collections::HashSet; + + let combinator = PositionCombinations::new(2, 4); + let result: HashSet<_> = combinator.into_iter().collect(); + let mut number_solutions = result.len(); + let mut solution = HashSet::new(); + solution.insert(vec![false, false, true, true]); + solution.insert(vec![false, true, false, true]); + solution.insert(vec![false, true, true, false]); + solution.insert(vec![false, true, true, true]); + solution.insert(vec![true, true, false, false]); + solution.insert(vec![true, false, true, false]); + solution.insert(vec![true, false, false, true]); + solution.insert(vec![true, false, true, true]); + solution.insert(vec![true, true, false, true]); + solution.insert(vec![true, true, true, false]); + solution.insert(vec![true, true, true, true]); + for item in solution { + assert!(result.contains(&item)); + number_solutions -= 1; + } + assert_eq!(number_solutions, 0); + } +} diff --git a/euler51/src/main.rs b/euler51/src/main.rs index f96361d..09f0359 100644 --- a/euler51/src/main.rs +++ b/euler51/src/main.rs @@ -1,4 +1,4 @@ -mod permutation; +mod combination; mod primes; use crate::primes::Primes; @@ -13,8 +13,8 @@ const DIGITS: [Int; 10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; // const MAX_VALUE: Int = 10_010_000; // const MAX_VALUE: Int = 99_999_999; -const LENGTH_OF_NUMBERS: usize = 5; -const MIN_LENGTH: usize = 2; +// const LENGTH_OF_NUMBERS: usize = 5; +// const MIN_LENGTH: usize = 2; fn main() { let primes = Primes::get_between(MIN_VALUE, MAX_VALUE); @@ -63,7 +63,7 @@ fn digits_to_num(vec: Vec) -> Int { #[cfg(test)] mod test { - use crate::{digits_to_num, num_to_digits, primes::Primes, Int, MAX_VALUE, MIN_VALUE}; + use crate::{digits_to_num, num_to_digits}; #[test] fn test_digits_to_num() { diff --git a/euler51/src/permutation.rs b/euler51/src/permutation.rs deleted file mode 100644 index 1ca36f9..0000000 --- a/euler51/src/permutation.rs +++ /dev/null @@ -1,75 +0,0 @@ -struct PositionPermut { - max_length: usize, - number_of_digits: usize, - idx: usize, - total_number_of_iterations: usize, -} - -impl Iterator for PositionPermut { - type Item = Vec; - - fn next(&mut self) -> Option { - if self.idx == (self.total_number_of_iterations) { - return None; - }; - let pos1 = self.idx % self.number_of_digits; - let pos0 = 0; - let x = vec![pos0 as i64, pos1 as i64]; - let result = Some(x); - self.idx += 1; - result - } -} - -impl PositionPermut { - fn new(max_length: usize) -> Self { - assert!(max_length >= 3); - let total_number_of_iterations = (1..max_length + 1).sum(); - Self { - max_length, - number_of_digits: 2, - idx: 0, - total_number_of_iterations, - } - } - fn test(&mut self) { - // length_of_numbers = 4 - // number_of_digits = 2 - [0, 1]; - [0, 2]; - [0, 3]; - [1, 2]; - [1, 3]; - [2, 3]; - // number_of_digits = 3 - [0, 1, 2]; - [0, 1, 3]; - [0, 2, 3]; - [1, 2, 3]; - } -} - -#[cfg(test)] -mod test { - #[test] - fn test_permutation() { - use crate::permutation::PositionPermut; - use std::collections::HashSet; - - let permutator = PositionPermut::new(3); - let result: HashSet<_> = permutator.into_iter().collect(); - let mut solution = HashSet::new(); - solution.insert(vec![0, 1]); - solution.insert(vec![0, 2]); - solution.insert(vec![0, 3]); - solution.insert(vec![1, 2]); - solution.insert(vec![1, 3]); - solution.insert(vec![2, 3]); - // solution.insert(vec![0, 1, 2]); - // solution.insert(vec![0, 1, 3]); - // solution.insert(vec![0, 2, 3]); - // solution.insert(vec![1, 2, 3]); - // assert_eq!(result.len(), solution.len()); - assert_eq!(result, solution); - } -}