rand: Delete all doc tests
None of these actually compile any more!
This commit is contained in:
parent
700e627cf7
commit
b53319a5bb
@ -56,18 +56,6 @@ impl Rand for Exp1 {
|
||||
///
|
||||
/// This distribution has density function: `f(x) = lambda *
|
||||
/// exp(-lambda * x)` for `x > 0`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{Exp, IndependentSample};
|
||||
///
|
||||
/// let exp = Exp::new(2.0);
|
||||
/// let v = exp.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from a Exp(2) distribution", v);
|
||||
/// ```
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Exp {
|
||||
/// `lambda` stored as `1/lambda`, since this is what we scale by.
|
||||
|
@ -37,18 +37,6 @@ use super::{IndependentSample, Sample, Exp};
|
||||
/// == 1`, and using the boosting technique described in [1] for
|
||||
/// `shape < 1`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{IndependentSample, Gamma};
|
||||
///
|
||||
/// let gamma = Gamma::new(2.0, 5.0);
|
||||
/// let v = gamma.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from a Gamma(2, 5) distribution", v);
|
||||
/// ```
|
||||
///
|
||||
/// [1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method
|
||||
/// for Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3
|
||||
/// (September 2000),
|
||||
@ -184,18 +172,6 @@ impl IndependentSample<f64> for GammaLargeShape {
|
||||
/// of `k` independent standard normal random variables. For other
|
||||
/// `k`, this uses the equivalent characterisation `χ²(k) = Gamma(k/2,
|
||||
/// 2)`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{ChiSquared, IndependentSample};
|
||||
///
|
||||
/// let chi = ChiSquared::new(11.0);
|
||||
/// let v = chi.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from a χ²(11) distribution", v)
|
||||
/// ```
|
||||
pub struct ChiSquared {
|
||||
repr: ChiSquaredRepr,
|
||||
}
|
||||
@ -242,18 +218,6 @@ impl IndependentSample<f64> for ChiSquared {
|
||||
/// This distribution is equivalent to the ratio of two normalised
|
||||
/// chi-squared distributions, that is, `F(m,n) = (χ²(m)/m) /
|
||||
/// (χ²(n)/n)`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{FisherF, IndependentSample};
|
||||
///
|
||||
/// let f = FisherF::new(2.0, 32.0);
|
||||
/// let v = f.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from an F(2, 32) distribution", v)
|
||||
/// ```
|
||||
pub struct FisherF {
|
||||
numer: ChiSquared,
|
||||
denom: ChiSquared,
|
||||
@ -287,18 +251,6 @@ impl IndependentSample<f64> for FisherF {
|
||||
|
||||
/// The Student t distribution, `t(nu)`, where `nu` is the degrees of
|
||||
/// freedom.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{StudentT, IndependentSample};
|
||||
///
|
||||
/// let t = StudentT::new(11.0);
|
||||
/// let v = t.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from a t(11) distribution", v)
|
||||
/// ```
|
||||
pub struct StudentT {
|
||||
chi: ChiSquared,
|
||||
dof: f64
|
||||
|
@ -90,24 +90,6 @@ pub struct Weighted<T> {
|
||||
/// `IndependentSample` traits. Note that `&T` is (cheaply) `Clone` for
|
||||
/// all `T`, as is `usize`, so one can store references or indices into
|
||||
/// another vector.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{Weighted, WeightedChoice, IndependentSample};
|
||||
///
|
||||
/// let mut items = vec!(Weighted { weight: 2, item: 'a' },
|
||||
/// Weighted { weight: 4, item: 'b' },
|
||||
/// Weighted { weight: 1, item: 'c' });
|
||||
/// let wc = WeightedChoice::new(&mut items[..]);
|
||||
/// let mut rng = rand::thread_rng();
|
||||
/// for _ in 0..16 {
|
||||
/// // on average prints 'a' 4 times, 'b' 8 and 'c' twice.
|
||||
/// println!("{}", wc.ind_sample(&mut rng));
|
||||
/// }
|
||||
/// ```
|
||||
pub struct WeightedChoice<'a, T:'a> {
|
||||
items: &'a mut [Weighted<T>],
|
||||
weight_range: Range<usize>
|
||||
|
@ -72,19 +72,6 @@ impl Rand for StandardNormal {
|
||||
///
|
||||
/// This uses the ZIGNOR variant of the Ziggurat method, see
|
||||
/// `StandardNormal` for more details.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{Normal, IndependentSample};
|
||||
///
|
||||
/// // mean 2, standard deviation 3
|
||||
/// let normal = Normal::new(2.0, 3.0);
|
||||
/// let v = normal.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from a N(2, 9) distribution", v)
|
||||
/// ```
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Normal {
|
||||
mean: f64,
|
||||
@ -121,19 +108,6 @@ impl IndependentSample<f64> for Normal {
|
||||
///
|
||||
/// If `X` is log-normal distributed, then `ln(X)` is `N(mean,
|
||||
/// std_dev**2)` distributed.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{LogNormal, IndependentSample};
|
||||
///
|
||||
/// // mean 2, standard deviation 3
|
||||
/// let log_normal = LogNormal::new(2.0, 3.0);
|
||||
/// let v = log_normal.ind_sample(&mut rand::thread_rng());
|
||||
/// println!("{} is from an ln N(2, 9) distribution", v)
|
||||
/// ```
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct LogNormal {
|
||||
norm: Normal
|
||||
|
@ -32,23 +32,6 @@ use distributions::{Sample, IndependentSample};
|
||||
/// including `high`, but this may be very difficult. All the
|
||||
/// primitive integer types satisfy this property, and the float types
|
||||
/// normally satisfy it, but rounding may mean `high` can occur.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::distributions::{IndependentSample, Range};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let between = Range::new(10, 10000);
|
||||
/// let mut rng = std::rand::thread_rng();
|
||||
/// let mut sum = 0;
|
||||
/// for _ in 0..1000 {
|
||||
/// sum += between.ind_sample(&mut rng);
|
||||
/// }
|
||||
/// println!("{}", sum);
|
||||
/// }
|
||||
/// ```
|
||||
pub struct Range<X> {
|
||||
low: X,
|
||||
range: X,
|
||||
|
@ -143,17 +143,6 @@ pub trait Rng : Sized {
|
||||
/// with new data, and may panic if this is impossible
|
||||
/// (e.g. reading past the end of a file that is being used as the
|
||||
/// source of randomness).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand, core)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut v = [0; 13579];
|
||||
/// thread_rng().fill_bytes(&mut v);
|
||||
/// println!("{:?}", &v[..]);
|
||||
/// ```
|
||||
fn fill_bytes(&mut self, dest: &mut [u8]) {
|
||||
// this could, in theory, be done by transmuting dest to a
|
||||
// [u64], but this is (1) likely to be undefined behaviour for
|
||||
@ -179,18 +168,6 @@ pub trait Rng : Sized {
|
||||
}
|
||||
|
||||
/// Return a random value of a `Rand` type.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut rng = thread_rng();
|
||||
/// let x: usize = rng.gen();
|
||||
/// println!("{}", x);
|
||||
/// println!("{:?}", rng.gen::<(f64, bool)>());
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
fn gen<T: Rand>(&mut self) -> T {
|
||||
Rand::rand(self)
|
||||
@ -198,19 +175,6 @@ pub trait Rng : Sized {
|
||||
|
||||
/// Return an iterator that will yield an infinite number of randomly
|
||||
/// generated items.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut rng = thread_rng();
|
||||
/// let x = rng.gen_iter::<usize>().take(10).collect::<Vec<usize>>();
|
||||
/// println!("{:?}", x);
|
||||
/// println!("{:?}", rng.gen_iter::<(f64, bool)>().take(5)
|
||||
/// .collect::<Vec<(f64, bool)>>());
|
||||
/// ```
|
||||
fn gen_iter<'a, T: Rand>(&'a mut self) -> Generator<'a, T, Self> {
|
||||
Generator { rng: self, _marker: PhantomData }
|
||||
}
|
||||
@ -226,50 +190,17 @@ pub trait Rng : Sized {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `low >= high`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut rng = thread_rng();
|
||||
/// let n: usize = rng.gen_range(0, 10);
|
||||
/// println!("{}", n);
|
||||
/// let m: f64 = rng.gen_range(-40.0f64, 1.3e5f64);
|
||||
/// println!("{}", m);
|
||||
/// ```
|
||||
fn gen_range<T: PartialOrd + SampleRange>(&mut self, low: T, high: T) -> T {
|
||||
assert!(low < high, "Rng.gen_range called with low >= high");
|
||||
Range::new(low, high).ind_sample(self)
|
||||
}
|
||||
|
||||
/// Return a bool with a 1 in n chance of true
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut rng = thread_rng();
|
||||
/// println!("{}", rng.gen_weighted_bool(3));
|
||||
/// ```
|
||||
fn gen_weighted_bool(&mut self, n: usize) -> bool {
|
||||
n <= 1 || self.gen_range(0, n) == 0
|
||||
}
|
||||
|
||||
/// Return an iterator of random characters from the set A-Z,a-z,0-9.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let s: String = thread_rng().gen_ascii_chars().take(10).collect();
|
||||
/// println!("{}", s);
|
||||
/// ```
|
||||
fn gen_ascii_chars<'a>(&'a mut self) -> AsciiGenerator<'a, Self> {
|
||||
AsciiGenerator { rng: self }
|
||||
}
|
||||
@ -277,18 +208,6 @@ pub trait Rng : Sized {
|
||||
/// Return a random element from `values`.
|
||||
///
|
||||
/// Return `None` if `values` is empty.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let choices = [1, 2, 4, 8, 16, 32];
|
||||
/// let mut rng = thread_rng();
|
||||
/// println!("{:?}", rng.choose(&choices));
|
||||
/// assert_eq!(rng.choose(&choices[..0]), None);
|
||||
/// ```
|
||||
fn choose<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
|
||||
if values.is_empty() {
|
||||
None
|
||||
@ -298,20 +217,6 @@ pub trait Rng : Sized {
|
||||
}
|
||||
|
||||
/// Shuffle a mutable slice in place.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand, core)]
|
||||
/// use std::rand::{thread_rng, Rng};
|
||||
///
|
||||
/// let mut rng = thread_rng();
|
||||
/// let mut y = [1, 2, 3];
|
||||
/// rng.shuffle(&mut y);
|
||||
/// println!("{:?}", y);
|
||||
/// rng.shuffle(&mut y);
|
||||
/// println!("{:?}", y);
|
||||
/// ```
|
||||
fn shuffle<T>(&mut self, values: &mut [T]) {
|
||||
let mut i = values.len();
|
||||
while i >= 2 {
|
||||
@ -362,33 +267,9 @@ impl<'a, R: Rng> Iterator for AsciiGenerator<'a, R> {
|
||||
/// the same stream of randomness multiple times.
|
||||
pub trait SeedableRng<Seed>: Rng {
|
||||
/// Reseed an RNG with the given seed.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{Rng, SeedableRng, StdRng};
|
||||
///
|
||||
/// let seed: &[_] = &[1, 2, 3, 4];
|
||||
/// let mut rng: StdRng = SeedableRng::from_seed(seed);
|
||||
/// println!("{}", rng.gen::<f64>());
|
||||
/// rng.reseed(&[5, 6, 7, 8]);
|
||||
/// println!("{}", rng.gen::<f64>());
|
||||
/// ```
|
||||
fn reseed(&mut self, Seed);
|
||||
|
||||
/// Create a new RNG with the given seed.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{Rng, SeedableRng, StdRng};
|
||||
///
|
||||
/// let seed: &[_] = &[1, 2, 3, 4];
|
||||
/// let mut rng: StdRng = SeedableRng::from_seed(seed);
|
||||
/// println!("{}", rng.gen::<f64>());
|
||||
/// ```
|
||||
fn from_seed(seed: Seed) -> Self;
|
||||
}
|
||||
|
||||
@ -484,16 +365,6 @@ impl Rand for XorShiftRng {
|
||||
/// Use `Closed01` for the closed interval `[0,1]`, and the default
|
||||
/// `Rand` implementation for `f32` and `f64` for the half-open
|
||||
/// `[0,1)`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{random, Open01};
|
||||
///
|
||||
/// let Open01(val) = random::<Open01<f32>>();
|
||||
/// println!("f32 from (0,1): {}", val);
|
||||
/// ```
|
||||
pub struct Open01<F>(pub F);
|
||||
|
||||
/// A wrapper for generating floating point numbers uniformly in the
|
||||
@ -502,16 +373,6 @@ pub struct Open01<F>(pub F);
|
||||
/// Use `Open01` for the closed interval `(0,1)`, and the default
|
||||
/// `Rand` implementation of `f32` and `f64` for the half-open
|
||||
/// `[0,1)`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{random, Closed01};
|
||||
///
|
||||
/// let Closed01(val) = random::<Closed01<f32>>();
|
||||
/// println!("f32 from [0,1]: {}", val);
|
||||
/// ```
|
||||
pub struct Closed01<F>(pub F);
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -99,34 +99,6 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default>
|
||||
}
|
||||
|
||||
/// Something that can be used to reseed an RNG via `ReseedingRng`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::{Rng, SeedableRng, StdRng};
|
||||
/// use std::rand::reseeding::{Reseeder, ReseedingRng};
|
||||
///
|
||||
/// struct TickTockReseeder { tick: bool }
|
||||
/// impl Reseeder<StdRng> for TickTockReseeder {
|
||||
/// fn reseed(&mut self, rng: &mut StdRng) {
|
||||
/// let val = if self.tick {0} else {1};
|
||||
/// rng.reseed(&[val]);
|
||||
/// self.tick = !self.tick;
|
||||
/// }
|
||||
/// }
|
||||
/// fn main() {
|
||||
/// let rsdr = TickTockReseeder { tick: true };
|
||||
///
|
||||
/// let inner = StdRng::new().unwrap();
|
||||
/// let mut rng = ReseedingRng::new(inner, 10, rsdr);
|
||||
///
|
||||
/// // this will repeat, because it gets reseeded very regularly.
|
||||
/// let s: String = rng.gen_ascii_chars().take(100).collect();
|
||||
/// println!("{}", s);
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
pub trait Reseeder<R> {
|
||||
/// Reseed the given RNG.
|
||||
fn reseed(&mut self, rng: &mut R);
|
||||
|
@ -54,174 +54,6 @@
|
||||
//! - On some systems (e.g. FreeBSD, OpenBSD and Mac OS X) there is no difference
|
||||
//! between the two sources. (Also note that, on some systems e.g. FreeBSD, both `/dev/random`
|
||||
//! and `/dev/urandom` may block once if the CSPRNG has not seeded yet.)
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```rust
|
||||
//! # #![feature(rand)]
|
||||
//! use std::rand;
|
||||
//! use std::rand::Rng;
|
||||
//!
|
||||
//! let mut rng = rand::thread_rng();
|
||||
//! if rng.gen() { // random bool
|
||||
//! println!("isize: {}, usize: {}", rng.gen::<isize>(), rng.gen::<usize>())
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ```rust
|
||||
//! # #![feature(rand)]
|
||||
//! use std::rand;
|
||||
//!
|
||||
//! let tuple = rand::random::<(f64, char)>();
|
||||
//! println!("{:?}", tuple)
|
||||
//! ```
|
||||
//!
|
||||
//! ## Monte Carlo estimation of π
|
||||
//!
|
||||
//! For this example, imagine we have a square with sides of length 2 and a unit
|
||||
//! circle, both centered at the origin. Since the area of a unit circle is π,
|
||||
//! we have:
|
||||
//!
|
||||
//! ```text
|
||||
//! (area of unit circle) / (area of square) = π / 4
|
||||
//! ```
|
||||
//!
|
||||
//! So if we sample many points randomly from the square, roughly π / 4 of them
|
||||
//! should be inside the circle.
|
||||
//!
|
||||
//! We can use the above fact to estimate the value of π: pick many points in the
|
||||
//! square at random, calculate the fraction that fall within the circle, and
|
||||
//! multiply this fraction by 4.
|
||||
//!
|
||||
//! ```
|
||||
//! # #![feature(rand)]
|
||||
//! use std::rand;
|
||||
//! use std::rand::distributions::{IndependentSample, Range};
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let between = Range::new(-1f64, 1.);
|
||||
//! let mut rng = rand::thread_rng();
|
||||
//!
|
||||
//! let total = 1_000_000;
|
||||
//! let mut in_circle = 0;
|
||||
//!
|
||||
//! for _ in 0..total {
|
||||
//! let a = between.ind_sample(&mut rng);
|
||||
//! let b = between.ind_sample(&mut rng);
|
||||
//! if a*a + b*b <= 1. {
|
||||
//! in_circle += 1;
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! // prints something close to 3.14159...
|
||||
//! println!("{}", 4. * (in_circle as f64) / (total as f64));
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Monty Hall Problem
|
||||
//!
|
||||
//! This is a simulation of the [Monty Hall Problem][]:
|
||||
//!
|
||||
//! > Suppose you're on a game show, and you're given the choice of three doors:
|
||||
//! > Behind one door is a car; behind the others, goats. You pick a door, say No. 1,
|
||||
//! > and the host, who knows what's behind the doors, opens another door, say No. 3,
|
||||
//! > which has a goat. He then says to you, "Do you want to pick door No. 2?"
|
||||
//! > Is it to your advantage to switch your choice?
|
||||
//!
|
||||
//! The rather unintuitive answer is that you will have a 2/3 chance of winning if
|
||||
//! you switch and a 1/3 chance of winning if you don't, so it's better to switch.
|
||||
//!
|
||||
//! This program will simulate the game show and with large enough simulation steps
|
||||
//! it will indeed confirm that it is better to switch.
|
||||
//!
|
||||
//! [Monty Hall Problem]: http://en.wikipedia.org/wiki/Monty_Hall_problem
|
||||
//!
|
||||
//! ```
|
||||
//! # #![feature(rand)]
|
||||
//! use std::rand;
|
||||
//! use std::rand::Rng;
|
||||
//! use std::rand::distributions::{IndependentSample, Range};
|
||||
//!
|
||||
//! struct SimulationResult {
|
||||
//! win: bool,
|
||||
//! switch: bool,
|
||||
//! }
|
||||
//!
|
||||
//! // Run a single simulation of the Monty Hall problem.
|
||||
//! fn simulate<R: Rng>(random_door: &Range<usize>, rng: &mut R) -> SimulationResult {
|
||||
//! let car = random_door.ind_sample(rng);
|
||||
//!
|
||||
//! // This is our initial choice
|
||||
//! let mut choice = random_door.ind_sample(rng);
|
||||
//!
|
||||
//! // The game host opens a door
|
||||
//! let open = game_host_open(car, choice, rng);
|
||||
//!
|
||||
//! // Shall we switch?
|
||||
//! let switch = rng.gen();
|
||||
//! if switch {
|
||||
//! choice = switch_door(choice, open);
|
||||
//! }
|
||||
//!
|
||||
//! SimulationResult { win: choice == car, switch: switch }
|
||||
//! }
|
||||
//!
|
||||
//! // Returns the door the game host opens given our choice and knowledge of
|
||||
//! // where the car is. The game host will never open the door with the car.
|
||||
//! fn game_host_open<R: Rng>(car: usize, choice: usize, rng: &mut R) -> usize {
|
||||
//! let choices = free_doors(&[car, choice]);
|
||||
//! rand::sample(rng, choices.into_iter(), 1)[0]
|
||||
//! }
|
||||
//!
|
||||
//! // Returns the door we switch to, given our current choice and
|
||||
//! // the open door. There will only be one valid door.
|
||||
//! fn switch_door(choice: usize, open: usize) -> usize {
|
||||
//! free_doors(&[choice, open])[0]
|
||||
//! }
|
||||
//!
|
||||
//! fn free_doors(blocked: &[usize]) -> Vec<usize> {
|
||||
//! (0..3).filter(|x| !blocked.contains(x)).collect()
|
||||
//! }
|
||||
//!
|
||||
//! fn main() {
|
||||
//! // The estimation will be more accurate with more simulations
|
||||
//! let num_simulations = 10000;
|
||||
//!
|
||||
//! let mut rng = rand::thread_rng();
|
||||
//! let random_door = Range::new(0, 3);
|
||||
//!
|
||||
//! let (mut switch_wins, mut switch_losses) = (0, 0);
|
||||
//! let (mut keep_wins, mut keep_losses) = (0, 0);
|
||||
//!
|
||||
//! println!("Running {} simulations...", num_simulations);
|
||||
//! for _ in 0..num_simulations {
|
||||
//! let result = simulate(&random_door, &mut rng);
|
||||
//!
|
||||
//! match (result.win, result.switch) {
|
||||
//! (true, true) => switch_wins += 1,
|
||||
//! (true, false) => keep_wins += 1,
|
||||
//! (false, true) => switch_losses += 1,
|
||||
//! (false, false) => keep_losses += 1,
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! let total_switches = switch_wins + switch_losses;
|
||||
//! let total_keeps = keep_wins + keep_losses;
|
||||
//!
|
||||
//! println!("Switched door {} times with {} wins and {} losses",
|
||||
//! total_switches, switch_wins, switch_losses);
|
||||
//!
|
||||
//! println!("Kept our choice {} times with {} wins and {} losses",
|
||||
//! total_keeps, keep_wins, keep_losses);
|
||||
//!
|
||||
//! // With a large number of simulations, the values should converge to
|
||||
//! // 0.667 and 0.333 respectively.
|
||||
//! println!("Estimated chance to win if we switch: {}",
|
||||
//! switch_wins as f32 / total_switches as f32);
|
||||
//! println!("Estimated chance to win if we don't: {}",
|
||||
//! keep_wins as f32 / total_keeps as f32);
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#![unstable(feature = "rand")]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user