rework sieve of Eratosthenes
This commit is contained in:
+42
-20
@@ -1,10 +1,14 @@
|
||||
extern crate num;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::Display;
|
||||
use std::fs::File;
|
||||
use std::hash::Hash;
|
||||
use std::io::Write;
|
||||
|
||||
use num::FromPrimitive;
|
||||
use num::Num;
|
||||
use num::ToPrimitive;
|
||||
use std::collections::HashSet;
|
||||
use std::hash::Hash;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Primes<T> {
|
||||
@@ -14,7 +18,7 @@ pub struct Primes<T> {
|
||||
|
||||
impl<T> Primes<T>
|
||||
where
|
||||
T: Num + ToPrimitive + FromPrimitive + Hash + Eq + PartialEq + Copy,
|
||||
T: Num + ToPrimitive + FromPrimitive + Hash + Eq + PartialEq + Copy + Display,
|
||||
{
|
||||
pub fn get_between(min_value: T, max_value: T) -> Self {
|
||||
let max_value = max_value.to_usize().unwrap();
|
||||
@@ -47,19 +51,13 @@ where
|
||||
let length = *max_value - *min_value;
|
||||
let mut result = vec![true; length];
|
||||
|
||||
for number_to_check in 2..(max_value / 2) {
|
||||
let mut last_number = number_to_check;
|
||||
loop {
|
||||
let current_number = last_number + number_to_check;
|
||||
if current_number < *min_value {
|
||||
last_number = current_number;
|
||||
let upper_limit = f64::sqrt(*max_value as f64).ceil() as usize;
|
||||
for i in 2..upper_limit {
|
||||
for multiple in ((i * i)..*max_value).step_by(i) {
|
||||
if &multiple < min_value {
|
||||
continue;
|
||||
}
|
||||
if current_number >= *max_value {
|
||||
break;
|
||||
}
|
||||
result[current_number - min_value] = false;
|
||||
last_number = current_number;
|
||||
result[multiple - min_value] = false;
|
||||
}
|
||||
}
|
||||
result
|
||||
@@ -72,10 +70,10 @@ where
|
||||
};
|
||||
}
|
||||
|
||||
// pub fn len(&self) -> usize {
|
||||
// debug_assert_eq!(self.vector.len(), self.set.len());
|
||||
// self.vector.len()
|
||||
// }
|
||||
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();
|
||||
@@ -88,11 +86,18 @@ where
|
||||
pub fn contains(&self, val: &T) -> bool {
|
||||
self.set.contains(val)
|
||||
}
|
||||
|
||||
pub fn save(&self, filename: &str) {
|
||||
let mut f = File::create(filename).unwrap();
|
||||
for p in &self.vector {
|
||||
writeln!(f, "{p}").unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::primes::Primes;
|
||||
use super::Primes;
|
||||
|
||||
#[test]
|
||||
fn test_example_prime() {
|
||||
@@ -113,8 +118,25 @@ mod test {
|
||||
#[test]
|
||||
fn test_pop() {
|
||||
let mut primes = Primes::get_between(10, 20);
|
||||
assert!(primes.contains(&11));
|
||||
assert_eq!(primes.len(), 4);
|
||||
assert!(primes.contains(&19));
|
||||
|
||||
primes.pop();
|
||||
|
||||
assert_eq!(primes.len(), 3);
|
||||
assert!(!primes.contains(&11));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_example_2() {
|
||||
let primes = Primes::get_between(2, 100_000);
|
||||
assert_eq!(primes.len(), 9_592);
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_performance() {
|
||||
let primes = Primes::get_between(2, 10_000_000);
|
||||
assert_eq!(primes.len(), 664_579);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user