finish 51
This commit is contained in:
+40
-12
@@ -1,5 +1,6 @@
|
||||
struct PositionCombinations {
|
||||
pub struct PositionCombinations {
|
||||
min_length: usize,
|
||||
max_length: usize,
|
||||
state: Vec<bool>,
|
||||
finished: bool,
|
||||
}
|
||||
@@ -8,13 +9,14 @@ impl Iterator for PositionCombinations {
|
||||
type Item = Vec<bool>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.finished {
|
||||
return None;
|
||||
}
|
||||
loop {
|
||||
let result = self.state.clone();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -22,11 +24,12 @@ impl Iterator for PositionCombinations {
|
||||
}
|
||||
|
||||
impl PositionCombinations {
|
||||
fn new(min_length: usize, max_length: usize) -> Self {
|
||||
let state = vec![false; max_length];
|
||||
pub fn new(min_length: usize, max_length: usize, length: usize) -> Self {
|
||||
let state = vec![false; length];
|
||||
let finished = false;
|
||||
Self {
|
||||
min_length,
|
||||
max_length,
|
||||
state,
|
||||
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)]
|
||||
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();
|
||||
#[test]
|
||||
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 solution = HashSet::new();
|
||||
solution.insert(vec![false, false, true, true]);
|
||||
@@ -67,7 +80,22 @@ mod test {
|
||||
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);
|
||||
}
|
||||
|
||||
#[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 {
|
||||
assert!(result.contains(&item));
|
||||
number_solutions -= 1;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
macro_rules! dbg_println {
|
||||
($($arg:tt)*) => (#[cfg(debug_assertions)] println!($($arg)*));
|
||||
}
|
||||
+96
-42
@@ -1,79 +1,133 @@
|
||||
mod combination;
|
||||
mod primes;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
use crate::combination::{PositionCombinations, ToString};
|
||||
use crate::primes::Primes;
|
||||
|
||||
type Int = i64;
|
||||
type Int = u64;
|
||||
|
||||
const MIN_VALUE: Int = 10_000;
|
||||
const MAX_VALUE: Int = 99_999;
|
||||
// EXAMPLE 1
|
||||
// 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];
|
||||
// const MIN_VALUE: Int = 10_000_000;
|
||||
// const MAX_VALUE: Int = 10_010_000;
|
||||
// const MAX_VALUE: Int = 99_999_999;
|
||||
|
||||
// const LENGTH_OF_NUMBERS: usize = 5;
|
||||
// OWN TEST
|
||||
// const MIN_VALUE: Int = 100;
|
||||
// const MAX_VALUE: Int = 999;
|
||||
// const LENGTH: usize = 3;
|
||||
// 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() {
|
||||
let primes = Primes::get_between(MIN_VALUE, MAX_VALUE);
|
||||
// let mut new_primes = primes.clone();
|
||||
for p in primes.vector.iter() {
|
||||
let mut candidates = vec![];
|
||||
let digits = num_to_digits(p);
|
||||
for d in DIGITS {
|
||||
let mut these_digits = digits.clone();
|
||||
these_digits[3] = d;
|
||||
these_digits[4] = d;
|
||||
let num = digits_to_num(these_digits);
|
||||
if primes.set.contains(&num) {
|
||||
candidates.push(num)
|
||||
let all_primes = Primes::get_between(MIN_VALUE, MAX_VALUE);
|
||||
let mut best_of_all_combinations = vec![];
|
||||
for pattern in PositionCombinations::new(MIN_LENGTH, MAX_LENGTH, LENGTH) {
|
||||
dbg_println!("{}", pattern.to_string());
|
||||
let mut best_this_combination = vec![];
|
||||
let mut primes_to_check = all_primes.clone();
|
||||
while let Some(first) = primes_to_check.pop() {
|
||||
let mut primes_matching_pattern = vec![];
|
||||
let digits = first.to_digits();
|
||||
for digit in DIGITS {
|
||||
let could_be_prime = digits
|
||||
.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 candidates.len() > 4 {
|
||||
println!("candidates");
|
||||
for c in &candidates {
|
||||
// new_primes.remove(c);
|
||||
println!("{c}");
|
||||
if primes_matching_pattern.len() > 2 {
|
||||
best_this_combination.push(primes_matching_pattern)
|
||||
}
|
||||
}
|
||||
if !best_this_combination.is_empty() {
|
||||
best_of_all_combinations.push(get_longest(best_this_combination, false));
|
||||
}
|
||||
// println!("new primes");
|
||||
// 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()
|
||||
}
|
||||
println!("{:#?}", get_longest(best_of_all_combinations, false));
|
||||
}
|
||||
|
||||
fn digits_to_num(vec: Vec<Int>) -> Int {
|
||||
fn get_longest(mut vec: Vec<Vec<Int>>, print: bool) -> Vec<Int> {
|
||||
if vec.is_empty() {
|
||||
panic!("cannot give the longest element of an empty vector")
|
||||
}
|
||||
if print {
|
||||
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 vec.iter().rev() {
|
||||
result += digit * position;
|
||||
for digit in self.iter().rev() {
|
||||
result += *digit as Int * position;
|
||||
position *= 10;
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{digits_to_num, num_to_digits};
|
||||
use crate::{ToDigits, ToNum};
|
||||
|
||||
#[test]
|
||||
fn test_digits_to_num() {
|
||||
let digits = vec![5, 7, 3, 8, 1];
|
||||
assert_eq!(digits_to_num(digits), 57381);
|
||||
assert_eq!(digits.to_num(), 57381);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_num_to_digits() {
|
||||
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;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Primes<T: Num + ToPrimitive> {
|
||||
pub vector: Vec<T>,
|
||||
pub set: HashSet<T>,
|
||||
pub struct Primes<T> {
|
||||
vector: Vec<T>,
|
||||
set: HashSet<T>,
|
||||
}
|
||||
|
||||
impl<T> Primes<T>
|
||||
@@ -38,6 +38,7 @@ where
|
||||
set.insert(prime);
|
||||
}
|
||||
}
|
||||
vector.reverse(); // so that self.pop removes the smallest prime
|
||||
Primes { vector, set }
|
||||
}
|
||||
|
||||
@@ -70,6 +71,23 @@ where
|
||||
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)]
|
||||
@@ -80,6 +98,23 @@ mod test {
|
||||
fn test_example_prime() {
|
||||
let primes = Primes::get_between(2, 99_999);
|
||||
assert!(primes.set.contains(&56003));
|
||||
assert!(primes.set.contains(&56993));
|
||||
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