




P

1




{\displaystyle P_{1}}







P

0




{\displaystyle P_{0}}







P

1




{\displaystyle P_{1}}







P

0




{\displaystyle P_{0}}







P

0




{\displaystyle P_{0}}







P

1




{\displaystyle P_{1}}




Task details

 Use your language's random number generator to create a function/method/subroutine/... randN that returns a one or a zero, but with one occurring, on average, 1 out of N times, where N is an integer from the range 3 to 6 inclusive.
 Create a function unbiased that uses only randN as its source of randomness to become an unbiased generator of random ones and zeroes.
 For N over its range, generate and show counts of the outputs of randN and unbiased(randN).


The actual unbiasing should be done by generating two numbers at a time from randN and only returning a 1 or 0 if they are different. As long as you always return the first number or always return the second number, the probabilities discussed above should take over the biased probability of randN.

This task is an implementation of Von Neumann debiasing, first described in a 1951 paper.




#![feature(inclusive_range_syntax)]
 
extern crate rand;
 
use rand::Rng;
 
fn rand_n<R: Rng>(rng: &mut R, n: u32) -> usize {
    rng.gen_weighted_bool(n) as usize // maps `false` to 0 and `true` to 1
}
 
fn unbiased<R: Rng>(rng: &mut R, n: u32) -> usize {
    let mut bit = rand_n(rng, n);
    while bit == rand_n(rng, n) {
        bit = rand_n(rng, n);
    }
    bit
}
 
fn main() {
    const SAMPLES: usize = 100_000;
    let mut rng = rand::weak_rng();
 
    println!(" Bias    rand_n  unbiased");
    for n in 3..=6 {
        let mut count_biased = 0;
        let mut count_unbiased = 0;
        for _ in 0..SAMPLES {
            count_biased += rand_n(&mut rng, n);
            count_unbiased += unbiased(&mut rng, n);
        }
 
        let b_percentage = 100.0 * count_biased as f64 / SAMPLES as f64;
        let ub_percentage = 100.0 * count_unbiased as f64 / SAMPLES as f64;
        println!(
            "bias {}:  {:0.2}%   {:0.2}%",
            n, b_percentage, ub_percentage
        );
    }
}