Documentation
use rand::Rng;
use rand_chacha::ChaCha8Rng;
use tracing::debug;

pub fn rand_one_in_vec(probability: &[usize], rng: &mut ChaCha8Rng) -> usize {
    let n = probability.len();
    if n == 1 {
        return 0;
    }
    let mut prob_sum = Vec::with_capacity(n);
    prob_sum.push(probability[0]);
    for i in 1..n {
        prob_sum.push(prob_sum[i - 1] + probability[i]);
    }
    debug!("{:?}", prob_sum);
    let r = rng.random_range(1..=prob_sum[n - 1]);
    if r <= prob_sum[0] {
        return 0;
    }
    for i in 1..n {
        if r > prob_sum[i - 1] && r <= prob_sum[i] {
            return i;
        }
    }
    0
}

#[test]
fn test() {
    use rand::SeedableRng;
    use tracing::info;

    crate::log::init_log_filter("info");

    let mut rng = ChaCha8Rng::seed_from_u64(0);
    let probability = vec![1, 1, 1, 1, 1];
    let mut count = vec![0; probability.len()];
    for _ in 0..10000 {
        let r = rand_one_in_vec(&probability, &mut rng);
        count[r] += 1;
    }
    info!("{:?}", count);
}