#[deny(missing_docs)]
pub struct Primes {
sieve: Vec<bool>,
primes: Vec<usize>,
}
impl Primes {
pub fn new() -> Self {
Primes { sieve: vec![true, true, false, false], primes: vec![2, 3] }
}
pub fn generate_to(&mut self, n: usize) {
if self.sieve.len() > n {
return;
}
let old_len = self.sieve.len();
{
let len = (n + 1).next_power_of_two();
self.sieve.reserve(len - self.sieve.len());
while self.sieve.len() < len {
self.sieve.push(false);
}
}
for prime in &self.primes {
for number in ((old_len + prime - 1) / prime * prime
..self.sieve.len())
.step_by(*prime)
{
self.sieve[number] = true;
}
}
for prime in old_len..self.sieve.len() {
if !self.sieve[prime] {
for number in (prime * prime..self.sieve.len()).step_by(prime) {
self.sieve[number] = true;
}
self.primes.push(prime);
}
}
}
pub fn generate_amount(&mut self, amount: usize) {
while self.primes.len() <= amount {
self.generate_to(self.sieve.len());
}
}
pub fn is_prime(&self, n: usize) -> bool {
if self.sieve.len() > n {
!self.sieve[n]
} else if n % 2 == 0 || n % 3 == 0 {
false
} else {
for prime in &self.primes {
if prime * prime > n {
return true;
}
if n % prime == 0 {
return false;
}
}
let start = {
let last = *self.primes.last().unwrap_or(&0);
if last % 6 == 1 {
last - 1
} else if last % 6 == 5 {
last + 1
} else {
6
}
};
for number in (start..).step_by(6) {
if (number - 1) * (number - 1) > n {
break;
}
if n % (number - 1) == 0 || n % (number + 1) == 0 {
return false;
}
}
true
}
}
pub fn is_prime_mut(&mut self, n: usize) -> bool {
self.generate_to(n);
!self.sieve[n]
}
pub fn sieve(&self) -> &[bool] {
&self.sieve
}
pub fn primes(&self) -> &[usize] {
&self.primes
}
pub fn iter(&mut self) -> Iter {
self.into_iter()
}
}
impl IntoIterator for Primes {
type Item = usize;
type IntoIter = IntoIter;
fn into_iter(self) -> Self::IntoIter {
IntoIter { primes: self, index: 0 }
}
}
impl<'a> IntoIterator for &'a mut Primes {
type Item = usize;
type IntoIter = Iter<'a>;
fn into_iter(self) -> Self::IntoIter {
Iter { primes: self, index: 0 }
}
}
pub struct IntoIter {
primes: Primes,
index: usize,
}
impl Iterator for IntoIter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
self.index += 1;
self.primes.generate_amount(self.index);
Some(self.primes.primes()[self.index - 1])
}
}
pub struct Iter<'a> {
primes: &'a mut Primes,
index: usize,
}
impl<'a> Iterator for Iter<'a> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
self.index += 1;
self.primes.generate_amount(self.index);
Some(self.primes.primes()[self.index - 1])
}
}
#[cfg(test)]
mod tests {
use crate::Primes;
#[test]
fn empty() {
assert_eq!(Primes::new().sieve, [true, true, false, false]);
}
#[test]
fn len() {
let mut primes = Primes::new();
primes.generate_to(4);
assert_eq!(primes.sieve().len(), 8);
}
#[test]
fn primes() {
let mut primes = Primes::new();
primes.generate_to(10);
assert_eq!(primes.primes(), [2, 3, 5, 7, 11, 13]);
assert_eq!(
primes.sieve(),
[
true, true, false, false, true, false, true, false, true, true,
true, false, true, false, true, true
]
);
primes.generate_to(20);
assert_eq!(primes.primes(), [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]);
assert_eq!(
primes.sieve(),
[
true, true, false, false, true, false, true, false, true, true,
true, false, true, false, true, true, true, false, true, false,
true, true, true, false, true, true, true, true, true, false,
true, false
]
);
}
#[test]
fn is_prime() {
let mut primes = Primes::new();
assert_eq!(primes.is_prime(0), false);
assert_eq!(primes.is_prime(1), false);
assert_eq!(primes.is_prime(2), true);
assert_eq!(primes.is_prime(3), true);
assert_eq!(primes.is_prime(4), false);
assert_eq!(primes.is_prime(5), true);
assert_eq!(primes.is_prime(100), false);
assert_eq!(primes.is_prime(101), true);
primes.generate_to(101);
assert_eq!(primes.is_prime(0), false);
assert_eq!(primes.is_prime(1), false);
assert_eq!(primes.is_prime(2), true);
assert_eq!(primes.is_prime(3), true);
assert_eq!(primes.is_prime(4), false);
assert_eq!(primes.is_prime(5), true);
assert_eq!(primes.is_prime(100), false);
assert_eq!(primes.is_prime(101), true);
}
#[test]
fn is_prime_mut() {
let mut primes = Primes::new();
assert_eq!(primes.is_prime_mut(0), false);
assert_eq!(primes.is_prime_mut(1), false);
assert_eq!(primes.is_prime_mut(2), true);
assert_eq!(primes.is_prime_mut(3), true);
assert_eq!(primes.is_prime_mut(4), false);
assert_eq!(primes.is_prime_mut(5), true);
assert_eq!(primes.is_prime_mut(100), false);
assert_eq!(primes.is_prime_mut(101), true);
}
#[test]
fn into_iter() {
let mut result = Vec::new();
for prime in Primes::new().into_iter().take(10) {
result.push(prime);
}
assert_eq!(result, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]);
}
#[test]
fn iter() {
let mut result = Vec::new();
for prime in Primes::new().iter().take(10) {
result.push(prime);
}
assert_eq!(result, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]);
}
}