Skip to content

Commit 0f82a68

Browse files
committed
remove the use of gen_range from seq
1 parent dbb1059 commit 0f82a68

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

src/seq.rs

+25-10
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub fn sample_iter<T, I, R>(rng: &mut R, iterable: I, amount: usize) -> Vec<T>
4545
// If the iterator stops once, then so do we.
4646
if reservoir.len() == amount {
4747
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;
4949
if let Some(spot) = reservoir.get_mut(k) {
5050
*spot = elem;
5151
}
@@ -161,10 +161,10 @@ fn sample_indices_inplace<R>(rng: &mut R, length: usize, amount: usize) -> Vec<u
161161
let mut indices: Vec<usize> = Vec::with_capacity(length);
162162
indices.extend(0..length);
163163
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;
165165
let tmp = indices[i];
166-
indices[i] = indices[j];
167-
indices[j] = tmp;
166+
indices[i] = indices[k];
167+
indices[k] = tmp;
168168
}
169169
indices.truncate(amount);
170170
debug_assert_eq!(indices.len(), amount);
@@ -188,22 +188,22 @@ fn sample_indices_cache<R>(
188188
let mut cache = HashMap::with_capacity(amount);
189189
let mut out = Vec::with_capacity(amount);
190190
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;
192192

193193
// equiv: let tmp = slice[i];
194194
let tmp = match cache.get(&i) {
195195
Some(e) => *e,
196196
None => i,
197197
};
198198

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) {
201201
Some(x) => *x,
202-
None => j,
202+
None => k,
203203
};
204204

205-
// equiv: slice[j] = tmp;
206-
cache.insert(j, tmp);
205+
// equiv: slice[k] = tmp;
206+
cache.insert(k, tmp);
207207

208208
// note that in the inplace version, slice[i] is automatically "returned" value
209209
out.push(x);
@@ -261,6 +261,21 @@ mod test {
261261
assert_eq!(sample_indices_cache(&mut r, 1, 0), vec![]);
262262
assert_eq!(sample_indices_cache(&mut r, 1, 1), vec![0]);
263263

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);
264279
}
265280

266281
#[test]

0 commit comments

Comments
 (0)