Skip to content

Instantly share code, notes, and snippets.

@zonyitoo
Last active April 14, 2017 05:29
Show Gist options
  • Save zonyitoo/50736ea1709533844852 to your computer and use it in GitHub Desktop.
Save zonyitoo/50736ea1709533844852 to your computer and use it in GitHub Desktop.
Sum of primes that not greater than N, with Rust and Miller-Rabin primality test
extern crate rand;
extern crate chrono;
use std::iter::range_step_inclusive;
use chrono::Local;
const MAX_N: u64 = 10_0000_0000;
fn main() {
const DEFAULT_ACCURACY: usize = 5;
let begin = Local::now();
let result = range_step_inclusive(3, MAX_N, 2)
.fold(2, |accu, num| if is_prime(num, DEFAULT_ACCURACY) { accu + num } else { accu });
let end = Local::now();
println!("Sum is {}, used {}", result, end - begin);
}
#[inline(always)]
fn pow_mod(mut a: u64, mut x: u64, n: u64) -> u64 {
let mut r = 1;
while x != 0 {
if (x & 1) == 1 {
r = a * r % n;
}
x >>= 1;
a = a * a % n;
}
r
}
#[inline(always)]
fn rand_between(a: u64, b: u64) -> u64 {
debug_assert!(b > a);
rand::random::<u64>() % (b - a) + a
}
#[inline(always)]
fn is_prime(n: u64, k: usize) -> bool {
if n == 2 || n == 3 {
return true;
} else if n <= 1 || (n & 1) == 0 {
return false;
}
let mut s = 0;
let mut m = n - 1;
while (m & 1) == 0 {
s += 1;
m >>= 1;
}
let d = (n - 1) / (1 << s);
'outer:
for _ in 0..k {
let a = rand_between(2, n - 2);
let mut x = pow_mod(a, d, n);
if x == 1 || x == n - 1 {
continue;
}
for _ in 1..s {
x = pow_mod(x, 2, n);
if x == 1 {
return false;
} else if x == n - 1 {
continue 'outer;
}
}
return false;
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment