[feature] get primes fast with sieve of Eratosthenes

This commit is contained in:
ddidderr 2023-12-02 09:20:20 +01:00
parent 3434c9d4f6
commit 4c56ab2779
Signed by: ddidderr
GPG Key ID: 3841F1C27E6F0E14
2 changed files with 56 additions and 0 deletions

12
src/main.rs Normal file
View File

@ -0,0 +1,12 @@
mod sieve;
use sieve::get_primes;
const MAX_SIEVED_PRIMES: usize = 100_000_000;
fn main() {
let primes = get_primes(MAX_SIEVED_PRIMES);
for prime in primes {
println!("{prime}");
}
}

44
src/sieve.rs Normal file
View File

@ -0,0 +1,44 @@
pub fn get_primes(max_nr: usize) -> Vec<u64> {
let mut sieve = vec![true; max_nr + 1];
let mut primes = Vec::new();
sieve[0] = false;
sieve[1] = false;
let mut nr = 2;
loop {
check_off_multiples_of_nr(nr, &mut sieve);
if !find_next_prime(&mut nr, &mut sieve) {
break;
}
primes.push(nr);
}
primes
}
fn find_next_prime(nr: &mut u64, sieve: &mut [bool]) -> bool {
if let Some((idx, _)) = sieve
.iter()
.enumerate()
.skip(usize::try_from(*nr).unwrap() + 1)
.find(|(_, val)| **val)
{
*nr = idx as u64;
return true;
}
false
}
fn check_off_multiples_of_nr(nr: u64, sieve: &mut [bool]) {
sieve
.iter_mut()
.skip(usize::try_from(nr * 2).unwrap())
.step_by(usize::try_from(nr).unwrap())
.for_each(|nr| *nr = false);
}