@@ -6,9 +6,9 @@ A basic library for finding primes, providing a basic Iterator over all primes.
6
6
The simplest usage is simply to create an `Iterator`:
7
7
8
8
```
9
- use primes::PrimeSet;
9
+ use primes::{TrialDivision, PrimeSet} ;
10
10
11
- let mut pset = PrimeSet ::new();
11
+ let mut pset = TrialDivision ::new();
12
12
13
13
for (ix, n) in pset.iter().enumerate().take(10) {
14
14
println!("Prime {}: {}", ix, n);
@@ -24,37 +24,37 @@ for the given test, and primes are cached for later use.
24
24
# Example: Find the first prime after 1 million
25
25
26
26
```
27
- use primes::PrimeSet;
27
+ use primes::{TrialDivision, PrimeSet} ;
28
28
29
- let mut pset = PrimeSet ::new();
29
+ let mut pset = TrialDivision ::new();
30
30
let (ix, n) = pset.find(1_000_000);
31
31
32
32
println!("Prime {}: {}", ix, n);
33
33
```
34
34
35
35
# Example: Find the first ten primes *after* the thousandth prime
36
36
```
37
- use primes::PrimeSet;
37
+ use primes::{TrialDivision, PrimeSet} ;
38
38
39
- let mut pset = PrimeSet ::new();
39
+ let mut pset = TrialDivision ::new();
40
40
for (ix, n) in pset.iter().enumerate().skip(1_000).take(10) {
41
41
println!("Prime {}: {}", ix, n);
42
42
}
43
43
```
44
44
45
45
# Example: Find the first prime greater than 1000
46
46
```
47
- use primes::PrimeSet;
47
+ use primes::{TrialDivision, PrimeSet} ;
48
48
49
- let mut pset = PrimeSet ::new();
49
+ let mut pset = TrialDivision ::new();
50
50
let (ix, n) = pset.find(1_000);
51
51
println!("The first prime after 1000 is the {}th prime: {}", ix, n);
52
52
53
53
assert_eq!(pset.find(n), (ix, n));
54
54
```
55
55
56
- For more info on use, see `PrimeSet`, a class which handles the Sieve and has multiple methods for
57
- iterating over primes.
56
+ For more info on use, see `PrimeSet`, a class which encapsulates most of the functionality and has
57
+ multiple methods for iterating over primes.
58
58
59
59
This also provides a few functions unconnected to `PrimeSet`, which will be faster for the first
60
60
case, but slower in the long term as they do not use any caching of primes.
@@ -66,31 +66,43 @@ use std::cmp::Ordering::{Equal, Greater, Less};
66
66
use std:: ops:: Index ;
67
67
use std:: slice;
68
68
69
- /** A prime generator, using the Sieve of Eratosthenes.
69
+ pub trait PrimeSetBasics {
70
+ /// Finds one more prime, and adds it to the list
71
+ fn expand ( & mut self ) ;
72
+
73
+ /// Return all primes found so far as a slice
74
+ fn list ( & self ) -> & [ u64 ] ;
75
+ }
70
76
71
- Create with `let mut pset = PrimeSet::new()`, and then use `pset.iter()` to iterate over all primes.
77
+ /**
78
+ A prime generator, using the Trial Division method.
79
+
80
+ Create with `let mut pset = TrialDivision::new()`, and then use `pset.iter()` to iterate over all
81
+ primes.
72
82
**/
73
83
#[ derive( Default ) ]
74
- pub struct PrimeSet {
84
+ pub struct TrialDivision {
75
85
lst : Vec < u64 > ,
76
86
}
77
87
78
88
/// An iterator over generated primes. Created by `PrimeSet::iter` or
79
89
/// `PrimeSet::generator`
80
- pub struct PrimeSetIter < ' a > {
81
- p : & ' a mut PrimeSet ,
90
+ pub struct PrimeSetIter < ' a , P : PrimeSet > {
91
+ p : & ' a mut P ,
82
92
n : usize ,
83
93
expand : bool ,
84
94
}
85
95
86
- impl PrimeSet {
96
+ impl TrialDivision {
87
97
/// A new prime generator, primed with 2 and 3
88
- pub fn new ( ) -> PrimeSet {
89
- PrimeSet { lst : vec ! [ 2 , 3 ] }
98
+ pub fn new ( ) -> TrialDivision {
99
+ TrialDivision { lst : vec ! [ 2 , 3 ] }
90
100
}
101
+ }
91
102
103
+ impl PrimeSetBasics for TrialDivision {
92
104
/// Finds one more prime, and adds it to the list
93
- pub fn expand ( & mut self ) {
105
+ fn expand ( & mut self ) {
94
106
let mut l: u64 = self . lst [ self . lst . len ( ) - 1 ] + 2 ;
95
107
let mut remainder = 0 ;
96
108
loop {
@@ -110,22 +122,24 @@ impl PrimeSet {
110
122
}
111
123
}
112
124
113
- /// Number of primes found so far
114
- pub fn len ( & self ) -> usize {
115
- self . lst . len ( )
125
+ /// Return all primes found so far as a slice
126
+ fn list ( & self ) -> & [ u64 ] {
127
+ & self . lst [ .. ]
116
128
}
129
+ }
117
130
118
- pub fn is_empty ( & self ) -> bool {
119
- false
131
+ pub trait PrimeSet : PrimeSetBasics + Sized {
132
+ /// Number of primes found so far
133
+ fn len ( & self ) -> usize {
134
+ self . list ( ) . len ( )
120
135
}
121
136
122
- /// Return all primes found so far as a slice
123
- pub fn list ( & self ) -> & [ u64 ] {
124
- & self . lst [ ..]
137
+ fn is_empty ( & self ) -> bool {
138
+ self . list ( ) . is_empty ( )
125
139
}
126
140
127
141
/// Iterator over all primes not yet found
128
- pub fn generator ( & mut self ) -> PrimeSetIter {
142
+ fn generator ( & mut self ) -> PrimeSetIter < Self > {
129
143
let myn = self . len ( ) ;
130
144
PrimeSetIter {
131
145
p : self ,
@@ -136,7 +150,7 @@ impl PrimeSet {
136
150
137
151
/// Iterator over all primes, starting with 2. If you don't care about the "state" of the
138
152
/// `PrimeSet`, this is what you want!
139
- pub fn iter ( & mut self ) -> PrimeSetIter {
153
+ fn iter ( & mut self ) -> PrimeSetIter < Self > {
140
154
PrimeSetIter {
141
155
p : self ,
142
156
n : 0 ,
@@ -145,17 +159,17 @@ impl PrimeSet {
145
159
}
146
160
147
161
/// Iterator over just the primes found so far
148
- pub fn iter_vec ( & self ) -> slice:: Iter < u64 > {
149
- self . lst . iter ( )
162
+ fn iter_vec ( & self ) -> slice:: Iter < u64 > {
163
+ self . list ( ) . iter ( )
150
164
}
151
165
152
166
/// Find the next largest prime from a number
153
167
///
154
168
/// Returns `(idx, prime)`
155
169
///
156
170
/// Note that if `n` is prime, then the output will be `(idx, n)`
157
- pub fn find ( & mut self , n : u64 ) -> ( usize , u64 ) {
158
- while n > * ( self . lst . last ( ) . unwrap_or ( & 0 ) ) {
171
+ fn find ( & mut self , n : u64 ) -> ( usize , u64 ) {
172
+ while n > * ( self . list ( ) . last ( ) . unwrap_or ( & 0 ) ) {
159
173
self . expand ( ) ;
160
174
}
161
175
self . find_vec ( n) . unwrap ( )
@@ -165,8 +179,7 @@ impl PrimeSet {
165
179
///
166
180
/// Note that this only requires primes up to `n.sqrt()` to be generated, and will generate
167
181
/// them as necessary on its own.
168
- #[ cfg_attr( feature = "cargo-clippy" , allow( clippy:: wrong_self_convention) ) ]
169
- pub fn is_prime ( & mut self , n : u64 ) -> bool {
182
+ fn is_prime ( & mut self , n : u64 ) -> bool {
170
183
if n <= 1 {
171
184
return false ;
172
185
}
@@ -189,8 +202,8 @@ impl PrimeSet {
189
202
/// Returns `(idx, prime)`
190
203
///
191
204
/// Note that if `n` is prime, then the output will be `(idx, n)`
192
- pub fn find_vec ( & self , n : u64 ) -> Option < ( usize , u64 ) > {
193
- if n > * ( self . lst . last ( ) . unwrap_or ( & 0 ) ) {
205
+ fn find_vec ( & self , n : u64 ) -> Option < ( usize , u64 ) > {
206
+ if n > * ( self . list ( ) . last ( ) . unwrap_or ( & 0 ) ) {
194
207
return None ;
195
208
}
196
209
@@ -200,8 +213,8 @@ impl PrimeSet {
200
213
// Binary search algorithm
201
214
while lim != 0 {
202
215
let ix = base + ( lim >> 1 ) ;
203
- match self . lst [ ix] . cmp ( & n) {
204
- Equal => return Some ( ( ix, self . lst [ ix] ) ) ,
216
+ match self . list ( ) [ ix] . cmp ( & n) {
217
+ Equal => return Some ( ( ix, self . list ( ) [ ix] ) ) ,
205
218
Less => {
206
219
base = ix + 1 ;
207
220
lim -= 1 ;
@@ -210,19 +223,19 @@ impl PrimeSet {
210
223
}
211
224
lim >>= 1 ;
212
225
}
213
- Some ( ( base, self . lst [ base] ) )
226
+ Some ( ( base, self . list ( ) [ base] ) )
214
227
}
215
228
216
229
/// Get the nth prime, even if we haven't yet found it
217
- pub fn get ( & mut self , index : usize ) -> u64 {
218
- for _ in 0 ..( index as isize ) + 1 - ( self . lst . len ( ) as isize ) {
230
+ fn get ( & mut self , index : usize ) -> u64 {
231
+ for _ in 0 ..( index as isize ) + 1 - ( self . list ( ) . len ( ) as isize ) {
219
232
self . expand ( ) ;
220
233
}
221
- self . lst [ index]
234
+ self . list ( ) [ index]
222
235
}
223
236
224
237
/// Get the prime factors of a number, starting from 2, including repeats
225
- pub fn prime_factors ( & mut self , n : u64 ) -> Vec < u64 > {
238
+ fn prime_factors ( & mut self , n : u64 ) -> Vec < u64 > {
226
239
if n == 1 {
227
240
return Vec :: new ( ) ;
228
241
}
@@ -246,17 +259,19 @@ impl PrimeSet {
246
259
}
247
260
}
248
261
249
- impl Index < usize > for PrimeSet {
262
+ impl < P : PrimeSetBasics > PrimeSet for P { }
263
+
264
+ impl Index < usize > for TrialDivision {
250
265
type Output = u64 ;
251
266
fn index ( & self , index : usize ) -> & u64 {
252
- & self . lst [ index]
267
+ & self . list ( ) [ index]
253
268
}
254
269
}
255
270
256
- impl < ' a > Iterator for PrimeSetIter < ' a > {
271
+ impl < ' a , P : PrimeSet > Iterator for PrimeSetIter < ' a , P > {
257
272
type Item = u64 ;
258
273
fn next ( & mut self ) -> Option < u64 > {
259
- while self . n >= self . p . len ( ) {
274
+ while self . n >= self . p . list ( ) . len ( ) {
260
275
if self . expand {
261
276
self . p . expand ( )
262
277
} else {
@@ -265,7 +280,7 @@ impl<'a> Iterator for PrimeSetIter<'a> {
265
280
}
266
281
self . n += 1 ;
267
282
268
- let m = self . p . lst [ self . n - 1 ] ;
283
+ let m = self . p . list ( ) [ self . n - 1 ] ;
269
284
270
285
Some ( m)
271
286
}
0 commit comments