Cod sursa(job #3235484)

Utilizator andreioneaAndrei Onea andreionea Data 18 iunie 2024 02:17:11
Problema Ciurul lui Eratosthenes Scor 30
Compilator rs Status done
Runda Arhiva educationala Marime 1.61 kb
use std::{fs::File, io::BufWriter};
use std::io::prelude::*;
fn pow(base: u64, exponent: u64, modulo: u64) -> u64 {
    let mut val = 1;
    let mut sq = base % modulo;
    let mut exponent = exponent;
    while exponent > 0 {
        if (exponent & 1) == 1 {
            val = (val * sq) % modulo;
        }
        exponent >>= 1;
        sq = (sq * sq) % modulo;
    }
    val
}

fn miller_rabin_test(a: u64, d: u64, s: u64, n: u64) -> bool {
    let mut val = pow(a, d, n);
    if (val == 1) || (val == (n - 1)) {
        return true;
    }
    for _ in 1..s {
        val = (val * val) % n;
        if val == (n - 1) {
            return true;
        }
    }
    false
}

fn is_prime(num: u64) -> bool {
    if num <= 1 {
        return false;
    }
    let s = (num - 1).trailing_zeros() as u64;
    let d = (num - 1) >> s;
    for a in [2, 3, 5] {
        if !miller_rabin_test(a, d, s, num) {
            return false;
        }
    }
    true
}
fn main() {
    let mut writer = BufWriter::new(File::create("ciur.out").unwrap());
    let n = std::fs::read_to_string("ciur.in").unwrap().trim().parse::<u64>().unwrap();
    let mut cnt = 0;
    if n >= 2 {
        cnt += 1;
    }
    if n >= 3 {
        cnt += 1;
    }
    if n >= 5 {
        cnt += 1;
    }
    let mut i = 1;
    loop {
        let v = 6 * i + 1;
        if v > n {
            break;
        }
        if is_prime(v) {
            cnt += 1;
        }

        let v = 6 * i + 5;
        if v > n {
            break;
        }
        if is_prime(v) {
            cnt += 1;
        }

        i += 1;
    }
    write!(writer, "{cnt}").expect("could not write to file");
}