1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! アトキンの篩
pub fn generate_primes(n: u64) -> Vec<bool> {
    let mut is_prime = vec![false; n as usize + 1];
    let sqrt_n = (n as f64).sqrt() as u64 + 1;

    for i in 1..sqrt_n {
        for j in 1..sqrt_n {
            let ii = i.pow(2);
            let jj = j.pow(2);

            let mut buff = 4 * ii + jj;
            let buff_mod12 = buff % 12;
            if buff <= n && (buff_mod12 == 1 || buff_mod12 == 5) {
                is_prime[buff as usize] ^= true;
            }

            buff = 3 * ii + jj;
            if buff <= n && buff % 12 == 7 {
                is_prime[buff as usize] ^= true;
            }

            if i <= j {
                continue;
            }

            buff = 3 * ii - jj;
            if i > j && buff <= n && buff % 12 == 11 {
                is_prime[buff as usize] ^= true;
            }
        }
    }
    for i in 5..sqrt_n {
        if !is_prime[i as usize] {
            continue;
        }
        let k = i * i;
        for j in (k..n).step_by(k as usize) {
            is_prime[j as usize] = false;
        }
    }
    is_prime[2] = true;
    is_prime[3] = true;
    is_prime
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_atkin() {
        let prime = generate_primes(1_000_000);

        let count: Vec<_> = prime
            .iter()
            .enumerate()
            .filter(|x| *x.1)
            .map(|x| x.0)
            .collect();
        assert_eq!(count.len(), 78498);
        assert_eq!(count[0], 2);
    }
}