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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
pub struct Sieve(Vec<bool>);
impl Sieve {
pub fn new(limit: usize) -> Self {
let mut sieve = vec![true; limit + 1];
sieve[0] = false;
if limit > 0 {
sieve[1] = false;
}
for i in 2..=limit {
if !sieve[i] {
continue;
}
for i in (i * i..=limit).step_by(i) {
sieve[i] = false;
}
}
Self(sieve)
}
pub fn is_prime(&self, n: usize) -> bool {
self.0[n]
}
pub fn primes<'a>(&'a self) -> impl Iterator<Item = usize> + 'a {
self.0
.iter()
.enumerate()
.filter(|(_, is_prime)| **is_prime)
.map(|(i, _)| i)
}
pub fn factorize(&self, mut n: usize) -> Vec<(usize, usize)> {
let mut factors = vec![];
for p in self.primes() {
let mut e = 0;
while n % p == 0 {
n /= p;
e += 1;
}
if e > 0 {
factors.push((p, e));
}
}
if n > 1 {
factors.push((n, 1));
}
factors
}
}
#[cfg(test)]
mod tests {
#[test]
fn is_prime() {
const LIMIT: usize = 10000;
let expected = primal_sieve::Sieve::new(LIMIT);
let expected = (0..=LIMIT)
.map(|i| expected.is_prime(i))
.collect::<Vec<_>>();
let super::Sieve(actual) = super::Sieve::new(LIMIT);
assert_eq!(expected, actual);
}
#[test]
fn primes() {
const LIMIT: usize = 10000;
let expected = primal_sieve::Sieve::new(LIMIT)
.primes_from(0)
.collect::<Vec<_>>();
let actual = super::Sieve::new(LIMIT).primes().collect::<Vec<_>>();
assert_eq!(expected, actual);
}
#[test]
fn factorize() {
const LIMIT: usize = 1000;
let sieve = super::Sieve::new(LIMIT);
const N: usize = 2 * 2 * 5 * 7561;
const EXPECTED: &[(usize, usize)] = &[(2, 2), (5, 1), (7561, 1)];
let actual = &sieve.factorize(N)[..];
assert_eq!(EXPECTED, actual);
}
}