variant/
lib.rs

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}