From 4c56ab2779a5028811617e6b32ff0a06c7ca4a01 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Sat, 2 Dec 2023 09:20:20 +0100 Subject: [PATCH] [feature] get primes fast with sieve of Eratosthenes --- src/main.rs | 12 ++++++++++++ src/sieve.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/main.rs create mode 100644 src/sieve.rs diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..0002aff --- /dev/null +++ b/src/main.rs @@ -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}"); + } +} diff --git a/src/sieve.rs b/src/sieve.rs new file mode 100644 index 0000000..d625d3a --- /dev/null +++ b/src/sieve.rs @@ -0,0 +1,44 @@ +pub fn get_primes(max_nr: usize) -> Vec { + 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); +}