Skip to content

Instantly share code, notes, and snippets.

@ckampfe
Last active April 25, 2021 01:59
Show Gist options
  • Save ckampfe/1665f7ff759ab64a5aec487ba5d904c2 to your computer and use it in GitHub Desktop.
Save ckampfe/1665f7ff759ab64a5aec487ba5d904c2 to your computer and use it in GitHub Desktop.
rust const Sieve of Eratosthenes
pub fn primes<const N: usize>() -> Vec<usize> {
let primes_array = sieve_of_eratosthenes::<N>();
std::array::IntoIter::new(primes_array)
.enumerate()
.filter_map(|(i, is_prime)| if is_prime { Some(i + 2) } else { None })
.collect()
}
pub const fn sieve_of_eratosthenes<const N: usize>() -> [bool; N] {
// true indicates "prime", false indicates "composite"
let mut numbers = [true; N];
let mut i: usize = 2;
loop {
// if we are still within the collection
if i <= N {
// if the n at the current index is a prime
if numbers[i - 2] {
let mut multiplier = 0;
let mut composite = compute_j(i, multiplier);
while composite <= N + 1 {
numbers[composite - 2] = false;
multiplier += 1;
composite = compute_j(i, multiplier);
}
}
i += 1;
} else {
break;
}
}
// special case handling in case the very last number is somehow prime
if numbers[N - 1] {
numbers[N - 1] = false;
}
return numbers;
}
const fn compute_j(i: usize, multiplier: usize) -> usize {
i.pow(2) + (i * multiplier)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
assert_eq!(primes::<5>(), vec![2, 3, 5]);
}
#[test]
fn it_works2() {
assert_eq!(primes::<30>(), vec![2, 3, 5, 7, 11, 13, 17, 19, 23, 29]);
}
#[test]
fn it_works3() {
assert_eq!(primes::<31>(), vec![2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]);
}
#[test]
fn it_works4() {
assert_eq!(primes::<1>(), vec![]);
}
#[test]
fn it_works5() {
assert_eq!(primes::<2>(), vec![2]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment