finish 51
This commit is contained in:
+42
-14
@@ -1,5 +1,6 @@
|
|||||||
struct PositionCombinations {
|
pub struct PositionCombinations {
|
||||||
min_length: usize,
|
min_length: usize,
|
||||||
|
max_length: usize,
|
||||||
state: Vec<bool>,
|
state: Vec<bool>,
|
||||||
finished: bool,
|
finished: bool,
|
||||||
}
|
}
|
||||||
@@ -8,13 +9,14 @@ impl Iterator for PositionCombinations {
|
|||||||
type Item = Vec<bool>;
|
type Item = Vec<bool>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if self.finished {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
loop {
|
loop {
|
||||||
let result = self.state.clone();
|
let result = self.state.clone();
|
||||||
self.increment();
|
self.increment();
|
||||||
if result.iter().filter(|x| **x).count() >= self.min_length {
|
if self.finished {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if (self.min_length..=self.max_length).contains(&result.iter().filter(|x| **x).count())
|
||||||
|
{
|
||||||
return Some(result);
|
return Some(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,11 +24,12 @@ impl Iterator for PositionCombinations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PositionCombinations {
|
impl PositionCombinations {
|
||||||
fn new(min_length: usize, max_length: usize) -> Self {
|
pub fn new(min_length: usize, max_length: usize, length: usize) -> Self {
|
||||||
let state = vec![false; max_length];
|
let state = vec![false; length];
|
||||||
let finished = false;
|
let finished = false;
|
||||||
Self {
|
Self {
|
||||||
min_length,
|
min_length,
|
||||||
|
max_length,
|
||||||
state,
|
state,
|
||||||
finished,
|
finished,
|
||||||
}
|
}
|
||||||
@@ -46,15 +49,25 @@ impl PositionCombinations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ToString {
|
||||||
|
fn to_string(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for Vec<bool> {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
self.iter().map(|b| if *b { 'x' } else { '.' }).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
#[test]
|
use crate::combination::PositionCombinations;
|
||||||
fn test_combination() {
|
use std::collections::HashSet;
|
||||||
use crate::combination::PositionCombinations;
|
|
||||||
use std::collections::HashSet;
|
|
||||||
|
|
||||||
let combinator = PositionCombinations::new(2, 4);
|
#[test]
|
||||||
let result: HashSet<_> = combinator.into_iter().collect();
|
fn test_combination_2_3_4() {
|
||||||
|
let combinator = PositionCombinations::new(2, 3, 4);
|
||||||
|
let result: Vec<_> = combinator.into_iter().collect();
|
||||||
let mut number_solutions = result.len();
|
let mut number_solutions = result.len();
|
||||||
let mut solution = HashSet::new();
|
let mut solution = HashSet::new();
|
||||||
solution.insert(vec![false, false, true, true]);
|
solution.insert(vec![false, false, true, true]);
|
||||||
@@ -67,7 +80,22 @@ mod test {
|
|||||||
solution.insert(vec![true, false, true, true]);
|
solution.insert(vec![true, false, true, true]);
|
||||||
solution.insert(vec![true, true, false, true]);
|
solution.insert(vec![true, true, false, true]);
|
||||||
solution.insert(vec![true, true, true, false]);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_combination_2_2_3() {
|
||||||
|
let combinator = PositionCombinations::new(2, 2, 3);
|
||||||
|
let result: Vec<_> = combinator.into_iter().collect();
|
||||||
|
let mut number_solutions = result.len();
|
||||||
|
let mut solution = HashSet::new();
|
||||||
|
solution.insert(vec![false, true, true]);
|
||||||
|
solution.insert(vec![true, false, true]);
|
||||||
|
solution.insert(vec![true, true, false]);
|
||||||
for item in solution {
|
for item in solution {
|
||||||
assert!(result.contains(&item));
|
assert!(result.contains(&item));
|
||||||
number_solutions -= 1;
|
number_solutions -= 1;
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
macro_rules! dbg_println {
|
||||||
|
($($arg:tt)*) => (#[cfg(debug_assertions)] println!($($arg)*));
|
||||||
|
}
|
||||||
+101
-47
@@ -1,79 +1,133 @@
|
|||||||
mod combination;
|
mod combination;
|
||||||
mod primes;
|
mod primes;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod macros;
|
||||||
|
|
||||||
|
use crate::combination::{PositionCombinations, ToString};
|
||||||
use crate::primes::Primes;
|
use crate::primes::Primes;
|
||||||
|
|
||||||
type Int = i64;
|
type Int = u64;
|
||||||
|
|
||||||
const MIN_VALUE: Int = 10_000;
|
// EXAMPLE 1
|
||||||
const MAX_VALUE: Int = 99_999;
|
// const MIN_VALUE: Int = 10;
|
||||||
|
// const MAX_VALUE: Int = 99;
|
||||||
|
// const LENGTH: usize = 2;
|
||||||
|
// const MIN_LENGTH: usize = 1;
|
||||||
|
|
||||||
const DIGITS: [Int; 10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
// OWN TEST
|
||||||
// const MIN_VALUE: Int = 10_000_000;
|
// const MIN_VALUE: Int = 100;
|
||||||
// const MAX_VALUE: Int = 10_010_000;
|
// const MAX_VALUE: Int = 999;
|
||||||
// const MAX_VALUE: Int = 99_999_999;
|
// const LENGTH: usize = 3;
|
||||||
|
|
||||||
// const LENGTH_OF_NUMBERS: usize = 5;
|
|
||||||
// const MIN_LENGTH: usize = 2;
|
// const MIN_LENGTH: usize = 2;
|
||||||
|
|
||||||
|
// EXAMPLE 2
|
||||||
|
// const MIN_VALUE: Int = 10_000;
|
||||||
|
// const MAX_VALUE: Int = 99_999;
|
||||||
|
// const LENGTH: usize = 5;
|
||||||
|
// const MIN_LENGTH: usize = 2;
|
||||||
|
|
||||||
|
// FINAL
|
||||||
|
const MIN_VALUE: Int = 100_000;
|
||||||
|
const MAX_VALUE: Int = 999_999;
|
||||||
|
const LENGTH: usize = 6;
|
||||||
|
const MIN_LENGTH: usize = 2;
|
||||||
|
|
||||||
|
const MAX_LENGTH: usize = LENGTH - 1;
|
||||||
|
const DIGITS: [u8; 10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let primes = Primes::get_between(MIN_VALUE, MAX_VALUE);
|
let all_primes = Primes::get_between(MIN_VALUE, MAX_VALUE);
|
||||||
// let mut new_primes = primes.clone();
|
let mut best_of_all_combinations = vec![];
|
||||||
for p in primes.vector.iter() {
|
for pattern in PositionCombinations::new(MIN_LENGTH, MAX_LENGTH, LENGTH) {
|
||||||
let mut candidates = vec![];
|
dbg_println!("{}", pattern.to_string());
|
||||||
let digits = num_to_digits(p);
|
let mut best_this_combination = vec![];
|
||||||
for d in DIGITS {
|
let mut primes_to_check = all_primes.clone();
|
||||||
let mut these_digits = digits.clone();
|
while let Some(first) = primes_to_check.pop() {
|
||||||
these_digits[3] = d;
|
let mut primes_matching_pattern = vec![];
|
||||||
these_digits[4] = d;
|
let digits = first.to_digits();
|
||||||
let num = digits_to_num(these_digits);
|
for digit in DIGITS {
|
||||||
if primes.set.contains(&num) {
|
let could_be_prime = digits
|
||||||
candidates.push(num)
|
.iter()
|
||||||
|
.zip(pattern.clone())
|
||||||
|
.map(|(d, b)| if b { digit } else { *d })
|
||||||
|
.collect::<Vec<u8>>()
|
||||||
|
.to_num();
|
||||||
|
if primes_to_check.contains(&could_be_prime) || could_be_prime == first {
|
||||||
|
primes_matching_pattern.push(could_be_prime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if primes_matching_pattern.len() > 2 {
|
||||||
|
best_this_combination.push(primes_matching_pattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if candidates.len() > 4 {
|
if !best_this_combination.is_empty() {
|
||||||
println!("candidates");
|
best_of_all_combinations.push(get_longest(best_this_combination, false));
|
||||||
for c in &candidates {
|
|
||||||
// new_primes.remove(c);
|
|
||||||
println!("{c}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// println!("new primes");
|
println!("{:#?}", get_longest(best_of_all_combinations, false));
|
||||||
// for p in new_primes.vector.iter() {
|
|
||||||
// println!("{p}");
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
fn num_to_digits(n: &Int) -> Vec<Int> {
|
|
||||||
n.to_string()
|
|
||||||
.chars()
|
|
||||||
.map(|x| x.to_digit(10).unwrap() as Int)
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn digits_to_num(vec: Vec<Int>) -> Int {
|
fn get_longest(mut vec: Vec<Vec<Int>>, print: bool) -> Vec<Int> {
|
||||||
let mut result = 0;
|
if vec.is_empty() {
|
||||||
let mut position = 1;
|
panic!("cannot give the longest element of an empty vector")
|
||||||
for digit in vec.iter().rev() {
|
}
|
||||||
result += digit * position;
|
if print {
|
||||||
position *= 10;
|
println!("{:#?}", vec);
|
||||||
|
}
|
||||||
|
vec.sort_by_key(|c| c.len());
|
||||||
|
let length = vec.last().unwrap().len();
|
||||||
|
vec.into_iter().find(|v| v.len() == length).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for Vec<u8> {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
self.iter().map(|d| d.to_string()).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ToDigits {
|
||||||
|
fn to_digits(&self) -> Vec<u8>;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ToNum {
|
||||||
|
fn to_num(&self) -> Int;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToDigits for Int {
|
||||||
|
fn to_digits(&self) -> Vec<u8> {
|
||||||
|
self.to_string()
|
||||||
|
.chars()
|
||||||
|
.map(|x| x.to_digit(10).unwrap() as u8)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToNum for Vec<u8> {
|
||||||
|
fn to_num(&self) -> Int {
|
||||||
|
let mut result = 0;
|
||||||
|
let mut position = 1;
|
||||||
|
for digit in self.iter().rev() {
|
||||||
|
result += *digit as Int * position;
|
||||||
|
position *= 10;
|
||||||
|
}
|
||||||
|
result
|
||||||
}
|
}
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::{digits_to_num, num_to_digits};
|
use crate::{ToDigits, ToNum};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_digits_to_num() {
|
fn test_digits_to_num() {
|
||||||
let digits = vec![5, 7, 3, 8, 1];
|
let digits = vec![5, 7, 3, 8, 1];
|
||||||
assert_eq!(digits_to_num(digits), 57381);
|
assert_eq!(digits.to_num(), 57381);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_num_to_digits() {
|
fn test_num_to_digits() {
|
||||||
let num = 83371;
|
let num = 83371;
|
||||||
assert_eq!(num_to_digits(&num), vec![8, 3, 3, 7, 1]);
|
assert_eq!(num.to_digits(), vec![8, 3, 3, 7, 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-3
@@ -7,9 +7,9 @@ use std::collections::HashSet;
|
|||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Primes<T: Num + ToPrimitive> {
|
pub struct Primes<T> {
|
||||||
pub vector: Vec<T>,
|
vector: Vec<T>,
|
||||||
pub set: HashSet<T>,
|
set: HashSet<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Primes<T>
|
impl<T> Primes<T>
|
||||||
@@ -38,6 +38,7 @@ where
|
|||||||
set.insert(prime);
|
set.insert(prime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vector.reverse(); // so that self.pop removes the smallest prime
|
||||||
Primes { vector, set }
|
Primes { vector, set }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +71,23 @@ where
|
|||||||
self.set.remove(num);
|
self.set.remove(num);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pub fn len(&self) -> usize {
|
||||||
|
// debug_assert_eq!(self.vector.len(), self.set.len());
|
||||||
|
// self.vector.len()
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub fn pop(&mut self) -> Option<T> {
|
||||||
|
let result = self.vector.pop();
|
||||||
|
if let Some(value) = result {
|
||||||
|
self.set.remove(&value);
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains(&self, val: &T) -> bool {
|
||||||
|
self.set.contains(val)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -80,6 +98,23 @@ mod test {
|
|||||||
fn test_example_prime() {
|
fn test_example_prime() {
|
||||||
let primes = Primes::get_between(2, 99_999);
|
let primes = Primes::get_between(2, 99_999);
|
||||||
assert!(primes.set.contains(&56003));
|
assert!(primes.set.contains(&56003));
|
||||||
|
assert!(primes.set.contains(&56993));
|
||||||
assert!(!primes.set.contains(&56002));
|
assert!(!primes.set.contains(&56002));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_remove() {
|
||||||
|
let mut primes = Primes::get_between(2, 9);
|
||||||
|
assert!(primes.contains(&7));
|
||||||
|
primes.remove(&7);
|
||||||
|
assert!(!primes.contains(&7));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pop() {
|
||||||
|
let mut primes = Primes::get_between(10, 20);
|
||||||
|
assert!(primes.contains(&11));
|
||||||
|
primes.pop();
|
||||||
|
assert!(!primes.contains(&11));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user