performance optimization in 51
This commit is contained in:
+37
-26
@@ -1,6 +1,8 @@
|
|||||||
extern crate combination;
|
extern crate combination;
|
||||||
extern crate primes;
|
extern crate primes;
|
||||||
|
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
use combination::PositionCombinations;
|
use combination::PositionCombinations;
|
||||||
use primes::Primes;
|
use primes::Primes;
|
||||||
|
|
||||||
@@ -23,37 +25,41 @@ const MIN_VALUE: Int = 100_000;
|
|||||||
const MAX_VALUE: Int = 999_999;
|
const MAX_VALUE: Int = 999_999;
|
||||||
const LENGTH: usize = 6;
|
const LENGTH: usize = 6;
|
||||||
const MIN_LENGTH: usize = 2;
|
const MIN_LENGTH: usize = 2;
|
||||||
|
const TARGET_LENGTH: usize = 8;
|
||||||
|
|
||||||
const MAX_LENGTH: usize = LENGTH - 1;
|
const MAX_LENGTH: usize = LENGTH - 1;
|
||||||
const DIGITS: [u8; 10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
const DIGITS: [u8; 10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let all_primes = Primes::get_between(MIN_VALUE, MAX_VALUE);
|
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) {
|
for pattern in PositionCombinations::new(MIN_LENGTH, MAX_LENGTH, LENGTH) {
|
||||||
let mut best_this_combination = vec![];
|
|
||||||
let mut primes_to_check = all_primes.clone();
|
let mut primes_to_check = all_primes.clone();
|
||||||
|
|
||||||
while let Some(first) = primes_to_check.pop() {
|
while let Some(first) = primes_to_check.pop() {
|
||||||
let mut primes_matching_pattern = vec![];
|
let mut primes_matching_pattern = vec![];
|
||||||
|
|
||||||
let digits = first.to_digits();
|
let digits = first.to_digits();
|
||||||
for digit in DIGITS {
|
for digit in DIGITS {
|
||||||
let could_be_prime = apply_transformation(&digits, digit, &pattern);
|
let could_be_prime =
|
||||||
|
replace_digits_according_to_pattern_with_digit(&digits, digit, &pattern);
|
||||||
if primes_to_check.contains(&could_be_prime) || could_be_prime == first {
|
if primes_to_check.contains(&could_be_prime) || could_be_prime == first {
|
||||||
primes_matching_pattern.push(could_be_prime);
|
primes_matching_pattern.push(could_be_prime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if primes_matching_pattern.len() > 2 {
|
if primes_matching_pattern.len() == TARGET_LENGTH {
|
||||||
best_this_combination.push(primes_matching_pattern);
|
println!("{primes_matching_pattern:#?}");
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !best_this_combination.is_empty() {
|
|
||||||
best_of_all_combinations.push(get_longest(best_this_combination));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("{:#?}", get_longest(best_of_all_combinations));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_transformation(prime_as_digits: &[u8], new_digit: u8, pattern: &[bool]) -> Int {
|
fn replace_digits_according_to_pattern_with_digit(
|
||||||
|
prime_as_digits: &[u8],
|
||||||
|
new_digit: u8,
|
||||||
|
pattern: &[bool],
|
||||||
|
) -> Int {
|
||||||
debug_assert_eq!(prime_as_digits.len(), pattern.len());
|
debug_assert_eq!(prime_as_digits.len(), pattern.len());
|
||||||
let mut multiplier = 1;
|
let mut multiplier = 1;
|
||||||
let result = prime_as_digits
|
let result = prime_as_digits
|
||||||
@@ -73,32 +79,31 @@ fn apply_transformation(prime_as_digits: &[u8], new_digit: u8, pattern: &[bool])
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_longest(mut vec: Vec<Vec<Int>>) -> Vec<Int> {
|
|
||||||
assert!(
|
|
||||||
!vec.is_empty(),
|
|
||||||
"cannot get the longest element of an empty vector"
|
|
||||||
);
|
|
||||||
vec.sort_by_key(|c| c.len());
|
|
||||||
let length = vec.last().unwrap().len();
|
|
||||||
vec.into_iter().find(|v| v.len() == length).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
trait ToDigits {
|
trait ToDigits {
|
||||||
fn to_digits(&self) -> Vec<u8>;
|
fn to_digits(&self) -> Vec<u8>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::needless_range_loop)]
|
||||||
impl ToDigits for Int {
|
impl ToDigits for Int {
|
||||||
fn to_digits(&self) -> Vec<u8> {
|
fn to_digits(&self) -> Vec<u8> {
|
||||||
self.to_string()
|
let oom = (*self as f64).log10().floor() as i32;
|
||||||
.chars()
|
let length = oom as usize + 1;
|
||||||
.map(|x| x.to_digit(10).unwrap() as u8)
|
let mut var = *self;
|
||||||
.collect()
|
let mut result = vec![0; length];
|
||||||
|
for i in 0..length as usize {
|
||||||
|
let power = 10_f64.powi(oom - i as i32);
|
||||||
|
let digit = (var as f64 / power).floor();
|
||||||
|
var -= (digit * power) as Int;
|
||||||
|
result[i] = digit as u8;
|
||||||
|
}
|
||||||
|
assert_eq!(var, 0);
|
||||||
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::{apply_transformation, ToDigits};
|
use crate::{replace_digits_according_to_pattern_with_digit, ToDigits};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_num_to_digits() {
|
fn test_num_to_digits() {
|
||||||
@@ -112,8 +117,14 @@ mod test {
|
|||||||
let new_digit = 0;
|
let new_digit = 0;
|
||||||
let pattern = [false, true, true, true, false, false];
|
let pattern = [false, true, true, true, false, false];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
apply_transformation(&prime_as_digits, new_digit, &pattern),
|
replace_digits_according_to_pattern_with_digit(&prime_as_digits, new_digit, &pattern),
|
||||||
500_021
|
500_021
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_to_digits() {
|
||||||
|
let num = 37871_u64;
|
||||||
|
assert_eq!(vec![3, 7, 8, 7, 1], num.to_digits());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user