diff --git a/lib/primes/src/lib.rs b/lib/primes/src/lib.rs index 9b8af4a..a1c406d 100644 --- a/lib/primes/src/lib.rs +++ b/lib/primes/src/lib.rs @@ -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 { @@ -14,7 +18,7 @@ pub struct Primes { impl Primes 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 { 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); + } }