1use mersenne_twister::MT19937_64;
2use rand::{Rng, SeedableRng};
3
4#[no_mangle]
5pub fn experiments(seed: u64, variants: &Vec<u8>) -> Vec<u8> {
6 let mut rng: MT19937_64 = SeedableRng::from_seed(seed);
7 variants.into_iter().map(|&max| {
8 rng.gen_range(0, max)
9 }).collect()
10}
11
12#[cfg(test)]
13mod tests {
14 use super::*;
15 use std::convert::TryInto;
16
17 fn generate_variant_max(n: u64) -> Vec<u8> {
18 (0..n).map(|_| { 255 }).collect()
19 }
20
21 #[test]
22 fn length_is_same_as_variants() {
23 let n = 100;
24 let result: Vec<u8> = experiments(0, &generate_variant_max(n));
25 assert_eq!(result.len() , 100);
26 }
27
28 #[test]
29 fn different_seeds_give_different_output() {
30 let first: Vec<u8> = experiments(0, &generate_variant_max(100));
31 let second: Vec<u8> = experiments(9_223_372_036_854_775_807, &generate_variant_max(100));
32 assert_ne!(first, second);
33 }
34
35 #[test]
36 fn around_half_of_experiments_above_128() {
37 let n = 100_000;
38 let result: Vec<u8> = experiments(0, &generate_variant_max(n));
39 let sum: i128 = result.into_iter()
40 .map(|exp_val| if exp_val > 128 {1} else {0})
41 .fold(0, |acc, x| acc + x);
42 let t: i128 = n.try_into().unwrap();
43 let tolerence = t / 16;
44 let tolerated = if (sum - (t / 2)).abs() < tolerence { true } else { false };
45 assert_eq!(tolerated, true);
46 }
47
48}