@@ -45,7 +45,7 @@ pub fn sample_iter<T, I, R>(rng: &mut R, iterable: I, amount: usize) -> Vec<T>
45
45
// If the iterator stops once, then so do we.
46
46
if reservoir. len ( ) == amount {
47
47
for ( i, elem) in iter. enumerate ( ) {
48
- let k = rng. gen_range ( 0 , i + 1 + amount) ;
48
+ let k = ( rng. next_f64 ( ) * ( i + 1 + amount) as f64 ) as usize ;
49
49
if let Some ( spot) = reservoir. get_mut ( k) {
50
50
* spot = elem;
51
51
}
@@ -161,10 +161,10 @@ fn sample_indices_inplace<R>(rng: &mut R, length: usize, amount: usize) -> Vec<u
161
161
let mut indices: Vec < usize > = Vec :: with_capacity ( length) ;
162
162
indices. extend ( 0 ..length) ;
163
163
for i in 0 ..amount {
164
- let j : usize = rng. gen_range ( i , length) ;
164
+ let k = ( rng. next_f64 ( ) * ( length - i ) as f64 ) as usize + i ;
165
165
let tmp = indices[ i] ;
166
- indices[ i] = indices[ j ] ;
167
- indices[ j ] = tmp;
166
+ indices[ i] = indices[ k ] ;
167
+ indices[ k ] = tmp;
168
168
}
169
169
indices. truncate ( amount) ;
170
170
debug_assert_eq ! ( indices. len( ) , amount) ;
@@ -188,22 +188,22 @@ fn sample_indices_cache<R>(
188
188
let mut cache = HashMap :: with_capacity ( amount) ;
189
189
let mut out = Vec :: with_capacity ( amount) ;
190
190
for i in 0 ..amount {
191
- let j : usize = rng. gen_range ( i , length) ;
191
+ let k = ( rng. next_f64 ( ) * ( length - i ) as f64 ) as usize + i ;
192
192
193
193
// equiv: let tmp = slice[i];
194
194
let tmp = match cache. get ( & i) {
195
195
Some ( e) => * e,
196
196
None => i,
197
197
} ;
198
198
199
- // equiv: slice[i] = slice[j ];
200
- let x = match cache. get ( & j ) {
199
+ // equiv: slice[i] = slice[k ];
200
+ let x = match cache. get ( & k ) {
201
201
Some ( x) => * x,
202
- None => j ,
202
+ None => k ,
203
203
} ;
204
204
205
- // equiv: slice[j ] = tmp;
206
- cache. insert ( j , tmp) ;
205
+ // equiv: slice[k ] = tmp;
206
+ cache. insert ( k , tmp) ;
207
207
208
208
// note that in the inplace version, slice[i] is automatically "returned" value
209
209
out. push ( x) ;
@@ -261,6 +261,21 @@ mod test {
261
261
assert_eq ! ( sample_indices_cache( & mut r, 1 , 0 ) , vec![ ] ) ;
262
262
assert_eq ! ( sample_indices_cache( & mut r, 1 , 1 ) , vec![ 0 ] ) ;
263
263
264
+ // Make sure lucky 777's aren't lucky
265
+ let slice = & [ 42 , 777 ] ;
266
+ let mut num_42 = 0 ;
267
+ let total = 1000 ;
268
+ for _ in 0 ..total {
269
+ let v = sample_slice ( & mut r, slice, 1 ) ;
270
+ assert_eq ! ( v. len( ) , 1 ) ;
271
+ let v = v[ 0 ] ;
272
+ assert ! ( v == 42 || v == 777 ) ;
273
+ if v == 42 {
274
+ num_42 += 1 ;
275
+ }
276
+ }
277
+ let ratio_42 = num_42 as f64 / 1000 as f64 ;
278
+ assert ! ( 0.4 <= ratio_42 || ratio_42 <= 0.6 , "{}" , ratio_42) ;
264
279
}
265
280
266
281
#[ test]
0 commit comments