more performance optimizations for 51
This commit is contained in:
@@ -12,7 +12,7 @@ use num::ToPrimitive;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Primes<T> {
|
pub struct Primes<T> {
|
||||||
vector: Vec<T>,
|
pub vector: Vec<T>,
|
||||||
set: HashSet<T>,
|
set: HashSet<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,14 +157,20 @@ mod test {
|
|||||||
|
|
||||||
#[ignore]
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_performance() {
|
fn test_performance_1() {
|
||||||
|
let _ = Primes::get_between(100_000, 999_999);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ignore]
|
||||||
|
#[test]
|
||||||
|
fn test_performance_2() {
|
||||||
let primes = Primes::get_between(2, 10_000_000);
|
let primes = Primes::get_between(2, 10_000_000);
|
||||||
assert_eq!(primes.len(), 664_579);
|
assert_eq!(primes.len(), 664_579);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ignore]
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_performance_2() {
|
fn test_performance_3() {
|
||||||
let primes = Primes::get_between(2, 1_000_000_000);
|
let primes = Primes::get_between(2, 1_000_000_000);
|
||||||
assert_eq!(primes.len(), 50_847_534);
|
assert_eq!(primes.len(), 50_847_534);
|
||||||
}
|
}
|
||||||
|
|||||||
+59
-16
@@ -1,7 +1,7 @@
|
|||||||
extern crate combination;
|
extern crate combination;
|
||||||
extern crate primes;
|
extern crate primes;
|
||||||
|
|
||||||
use std::process::exit;
|
use std::{collections::HashSet, process::exit};
|
||||||
|
|
||||||
use combination::PositionCombinations;
|
use combination::PositionCombinations;
|
||||||
use primes::Primes;
|
use primes::Primes;
|
||||||
@@ -32,18 +32,26 @@ 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 processed_cases = HashSet::new();
|
||||||
|
let mut primes_matching_pattern = Vec::with_capacity(TARGET_LENGTH);
|
||||||
|
|
||||||
for pattern in PositionCombinations::new(MIN_LENGTH, MAX_LENGTH, LENGTH) {
|
for pattern in PositionCombinations::new(MIN_LENGTH, MAX_LENGTH, LENGTH) {
|
||||||
let mut primes_to_check = all_primes.clone();
|
for prime in &all_primes.vector {
|
||||||
|
primes_matching_pattern.clear();
|
||||||
|
|
||||||
while let Some(first) = primes_to_check.pop() {
|
let digits = prime.to_digits();
|
||||||
let mut primes_matching_pattern = vec![];
|
|
||||||
|
let case = get_case_string(&digits, &pattern);
|
||||||
|
if processed_cases.contains(&case) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
processed_cases.insert(case.clone());
|
||||||
|
}
|
||||||
|
|
||||||
let digits = first.to_digits();
|
|
||||||
for digit in DIGITS {
|
for digit in DIGITS {
|
||||||
let could_be_prime =
|
let could_be_prime =
|
||||||
replace_digits_according_to_pattern_with_digit(&digits, digit, &pattern);
|
replace_digits_with_new_digit_according_to_pattern(&digits, digit, &pattern);
|
||||||
if primes_to_check.contains(&could_be_prime) || could_be_prime == first {
|
if all_primes.contains(&could_be_prime) {
|
||||||
primes_matching_pattern.push(could_be_prime);
|
primes_matching_pattern.push(could_be_prime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,7 +63,15 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_digits_according_to_pattern_with_digit(
|
fn get_case_string(digits: &[u8], pattern: &[bool]) -> String {
|
||||||
|
digits
|
||||||
|
.iter()
|
||||||
|
.zip(pattern)
|
||||||
|
.map(|(d, b)| if *b { '*' } else { *d as char })
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn replace_digits_with_new_digit_according_to_pattern(
|
||||||
prime_as_digits: &[u8],
|
prime_as_digits: &[u8],
|
||||||
new_digit: u8,
|
new_digit: u8,
|
||||||
pattern: &[bool],
|
pattern: &[bool],
|
||||||
@@ -86,24 +102,36 @@ trait ToDigits {
|
|||||||
#[allow(clippy::needless_range_loop)]
|
#[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> {
|
||||||
let oom = (*self as f64).log10().floor() as i32;
|
let oom = get_order_of_magnitude(*self);
|
||||||
let length = oom as usize + 1;
|
let length = oom as usize;
|
||||||
let mut var = *self;
|
let mut var = *self;
|
||||||
let mut result = vec![0; length];
|
let mut result = vec![0; length];
|
||||||
for i in 0..length as usize {
|
for i in 0..length {
|
||||||
let power = 10_f64.powi(oom - i as i32);
|
let power = 10_u64.pow(oom - i as u32 - 1);
|
||||||
let digit = (var as f64 / power).floor();
|
let digit = var / power;
|
||||||
var -= (digit * power) as Int;
|
var -= (digit * power) as Int;
|
||||||
result[i] = digit as u8;
|
result[i] = digit as u8;
|
||||||
}
|
}
|
||||||
assert_eq!(var, 0);
|
debug_assert_eq!(var, 0);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_order_of_magnitude(x: Int) -> u32 {
|
||||||
|
let mut tmp = 1;
|
||||||
|
let mut oom = 1;
|
||||||
|
while tmp - 1 < x {
|
||||||
|
oom += 1;
|
||||||
|
tmp *= 10;
|
||||||
|
}
|
||||||
|
oom - 1
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::{replace_digits_according_to_pattern_with_digit, ToDigits};
|
use crate::{
|
||||||
|
get_order_of_magnitude, replace_digits_with_new_digit_according_to_pattern, ToDigits,
|
||||||
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_num_to_digits() {
|
fn test_num_to_digits() {
|
||||||
@@ -117,7 +145,11 @@ 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!(
|
||||||
replace_digits_according_to_pattern_with_digit(&prime_as_digits, new_digit, &pattern),
|
replace_digits_with_new_digit_according_to_pattern(
|
||||||
|
&prime_as_digits,
|
||||||
|
new_digit,
|
||||||
|
&pattern
|
||||||
|
),
|
||||||
500_021
|
500_021
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -127,4 +159,15 @@ mod test {
|
|||||||
let num = 37871_u64;
|
let num = 37871_u64;
|
||||||
assert_eq!(vec![3, 7, 8, 7, 1], num.to_digits());
|
assert_eq!(vec![3, 7, 8, 7, 1], num.to_digits());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_oom() {
|
||||||
|
assert_eq!(get_order_of_magnitude(3), 1);
|
||||||
|
assert_eq!(get_order_of_magnitude(9), 1);
|
||||||
|
assert_eq!(get_order_of_magnitude(10), 2);
|
||||||
|
assert_eq!(get_order_of_magnitude(32), 2);
|
||||||
|
assert_eq!(get_order_of_magnitude(10_000), 5);
|
||||||
|
assert_eq!(get_order_of_magnitude(10_001), 5);
|
||||||
|
assert_eq!(get_order_of_magnitude(37_871), 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user