A Prime Iterator in rust

Inspired by Alessio Saltarin’s Primality Test in Scala, I thought that it would be interesting to implement the same primality test in rust and then use this test as a means to build an Iterator that lazily generates prime numbers.

The primality test …


This content originally appeared on DEV Community and was authored by David Berry

Inspired by Alessio Saltarin's Primality Test in Scala, I thought that it would be interesting to implement the same primality test in rust and then use this test as a means to build an Iterator that lazily generates prime numbers.

The primality test is based on the fact that all primes greater than 3 are of the form 6k ± 1, where k is any integer greater than 0. The rust version of this algorithm is:

pub fn is_prime(n: u64) -> bool {
  if n < 4 {
    n > 1
  } else if n % 2 == 0 || n % 3 == 0 {
    false
  } else {
    let max_p = (n as f64).sqrt().ceil() as u64;
    match (5..=max_p).step_by(6).find(|p| n % p == 0 || n % (p+2) == 0) {
      Some(_) => false,
      None => true
    }
  }
}

is_prime first tests for n<4 and returns n>1. n=2 or n=3 will return true all other n<4 return false. The next test checks if n is an even multiple of 2 or 3. If it is, return false as n is not prime.

The final test checks to see if n is evenly divisible by any 6k ± 1 up to the square root of n. This is done by starting at 5 and checking if n is an even multiple of 5 or 5+2, 6-1 or 6+1 respectively. If it is an even multiple we will return false, if not we add 6 and test again. If no even multiple is found, n is prime and return true.

Many will point out that using sqrt() and ceil() are expensive, but I only use it once up front to get the upper bound for the comparison. This removes the need to square the 6k ± 1 in the test loop to determine when to break. It also allowed me to use the range (5..=max_p).step_by(6).find with the predicate |p| n % p == 0 || n % (p+2) == 0 to identify non-primes. I add that to a match statement to return false if a non-prime is identified and true if n is prime.

Now that we have a primality test we can construct the lazy prime Iterator in rust. The code for the Iterator is:

pub struct Prime {
  last: u64,
  next: u64
}

impl Prime {
  pub fn new() -> Prime {
    Prime {
      last: 2,
      next: 3
    }
  }
}

impl Iterator for Prime {
  type Item = u64;

  fn next(&mut self) -> Option<Self::Item> {
    let prime = self.last;
    self.last = self.next;
    loop {
      self.next += match self.next%6 {
        1 => 4,
        _ => 2,
      };
      if is_prime(self.next) {
        break;
      }
    }
    Some(prime)
  }
}

A new Prime starts off with last=2 and next=3. This allowed me to ignore the special case of two primes being only one digit apart. The next function saves the prime in last which it will return. It then moves next into last and calculates a new next. It makes use of the fact that all primes greater than 3 are of the form 6k ± 1. So if the latest test prime is 6k-1 we add 2 to get the next possible prime. If the latest test prime is 6K+1 we add 4 to get the next possible prime. We accomplish this with p modulo 6, where p is the latest test prime. If p modulo 6 is 1 then we have a 6k+1 number and need to add 4 to get to the next test prime of 6k-1. If p modulo 6 is 5 or 3, then we add 2 to get to the next 6k+1 number. _ => 2 is the catch all that let's us catch the initial state of n=3 and any state where n=6k-1.

This iterator operates with constant memory and only generates one prime at a time.

Full code can be found on GitHub


This content originally appeared on DEV Community and was authored by David Berry


Print Share Comment Cite Upload Translate Updates
APA

David Berry | Sciencx (2021-11-07T19:46:38+00:00) A Prime Iterator in rust. Retrieved from https://www.scien.cx/2021/11/07/a-prime-iterator-in-rust/

MLA
" » A Prime Iterator in rust." David Berry | Sciencx - Sunday November 7, 2021, https://www.scien.cx/2021/11/07/a-prime-iterator-in-rust/
HARVARD
David Berry | Sciencx Sunday November 7, 2021 » A Prime Iterator in rust., viewed ,<https://www.scien.cx/2021/11/07/a-prime-iterator-in-rust/>
VANCOUVER
David Berry | Sciencx - » A Prime Iterator in rust. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/11/07/a-prime-iterator-in-rust/
CHICAGO
" » A Prime Iterator in rust." David Berry | Sciencx - Accessed . https://www.scien.cx/2021/11/07/a-prime-iterator-in-rust/
IEEE
" » A Prime Iterator in rust." David Berry | Sciencx [Online]. Available: https://www.scien.cx/2021/11/07/a-prime-iterator-in-rust/. [Accessed: ]
rf:citation
» A Prime Iterator in rust | David Berry | Sciencx | https://www.scien.cx/2021/11/07/a-prime-iterator-in-rust/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.