improve primes lib
This commit is contained in:
+11
-11
@@ -26,18 +26,18 @@ where
|
|||||||
assert!(min_value > 1);
|
assert!(min_value > 1);
|
||||||
assert!(max_value > min_value);
|
assert!(max_value > min_value);
|
||||||
Self::from_array(
|
Self::from_array(
|
||||||
Self::get_prime_numbers_array(&min_value, &max_value),
|
&Self::get_prime_numbers_array(min_value, max_value),
|
||||||
&min_value,
|
min_value,
|
||||||
&max_value,
|
max_value,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_array(array: Vec<bool>, min_value: &usize, max_value: &usize) -> Self {
|
fn from_array(array: &[bool], min_value: usize, max_value: usize) -> Self {
|
||||||
let number_of_primes = array.iter().filter(|b| **b).count();
|
let number_of_primes = array.iter().filter(|b| **b).count();
|
||||||
let mut vector = Vec::with_capacity(number_of_primes);
|
let mut vector = Vec::with_capacity(number_of_primes);
|
||||||
let mut set = HashSet::with_capacity(number_of_primes);
|
let mut set = HashSet::with_capacity(number_of_primes);
|
||||||
|
|
||||||
for number in *min_value..*max_value {
|
for number in min_value..max_value {
|
||||||
let idx = number - min_value;
|
let idx = number - min_value;
|
||||||
// SAFETY: see considerations in get_prime_numbers_array
|
// SAFETY: see considerations in get_prime_numbers_array
|
||||||
if unsafe { *array.get_unchecked(idx) } {
|
if unsafe { *array.get_unchecked(idx) } {
|
||||||
@@ -51,16 +51,16 @@ where
|
|||||||
Primes { vector, set }
|
Primes { vector, set }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_prime_numbers_array(min_value: &usize, max_value: &usize) -> Vec<bool> {
|
fn get_prime_numbers_array(min_value: usize, max_value: usize) -> Vec<bool> {
|
||||||
// Sieve of Eratosthenes
|
// Sieve of Eratosthenes
|
||||||
let length = *max_value - *min_value;
|
let length = max_value - min_value;
|
||||||
let mut result = vec![true; length];
|
let mut result = vec![true; length];
|
||||||
|
|
||||||
let upper_limit = Self::calc_upper_limit(max_value);
|
let upper_limit = Self::calc_upper_limit(max_value);
|
||||||
for i in 2..upper_limit {
|
for i in 2..upper_limit {
|
||||||
let skip = Self::find_number_to_skip_until_min_value(min_value, i);
|
let skip = Self::find_number_to_skip_until_min_value(min_value, i);
|
||||||
|
|
||||||
for multiple in (i * i..*max_value).step_by(i).skip(skip) {
|
for multiple in (i * i..max_value).step_by(i).skip(skip) {
|
||||||
let idx = multiple - min_value;
|
let idx = multiple - min_value;
|
||||||
// SAFETY: `multiple` will always be between min_value and max_value
|
// SAFETY: `multiple` will always be between min_value and max_value
|
||||||
// (which define the length of the array), therfore idx is always smaller than the
|
// (which define the length of the array), therfore idx is always smaller than the
|
||||||
@@ -72,11 +72,11 @@ where
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calc_upper_limit(max_value: &usize) -> usize {
|
fn calc_upper_limit(max_value: usize) -> usize {
|
||||||
f64::sqrt(*max_value as f64).ceil() as usize
|
f64::sqrt(max_value as f64).ceil() as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_number_to_skip_until_min_value(min_value: &usize, i: usize) -> usize {
|
fn find_number_to_skip_until_min_value(min_value: usize, i: usize) -> usize {
|
||||||
((min_value.saturating_sub(i * i)) as f64 / i as f64).ceil() as usize
|
((min_value.saturating_sub(i * i)) as f64 / i as f64).ceil() as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user