aboutsummaryrefslogtreecommitdiff
path: root/rand/examples
diff options
context:
space:
mode:
authorDaniel Mueller <deso@posteo.net>2019-01-02 21:14:10 -0800
committerDaniel Mueller <deso@posteo.net>2019-01-02 21:14:10 -0800
commitecf3474223ca3d16a10f12dc2272e3b0ed72c1bb (patch)
tree03134a683791176b49ef5c92e8d6acd24c3b5a9b /rand/examples
parent686f61b75055ecb02baf9d9449525ae447a3bed1 (diff)
downloadnitrocli-ecf3474223ca3d16a10f12dc2272e3b0ed72c1bb.tar.gz
nitrocli-ecf3474223ca3d16a10f12dc2272e3b0ed72c1bb.tar.bz2
Update nitrokey crate to 0.2.3
This change updates the nitrokey crate to version 0.2.3. This version bumps the rand crate used to 0.6.1, which in turn requires an additional set of dependencies. Import subrepo nitrokey/:nitrokey at b3e2adc5bb1300441ca74cc7672617c042f3ea31 Import subrepo rand/:rand at 73613ff903512e9503e41cc8ba9eae76269dc598 Import subrepo rustc_version/:rustc_version at 0294f2ba2018bf7be672abd53db351ce5055fa02 Import subrepo semver-parser/:semver-parser at 750da9b11a04125231b1fb293866ca036845acee Import subrepo semver/:semver at 5eb6db94fa03f4d5c64a625a56188f496be47598
Diffstat (limited to 'rand/examples')
-rw-r--r--rand/examples/monte-carlo.rs51
-rw-r--r--rand/examples/monty-hall.rs116
2 files changed, 167 insertions, 0 deletions
diff --git a/rand/examples/monte-carlo.rs b/rand/examples/monte-carlo.rs
new file mode 100644
index 0000000..9162996
--- /dev/null
+++ b/rand/examples/monte-carlo.rs
@@ -0,0 +1,51 @@
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2013-2018 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! # Monte Carlo estimation of π
+//!
+//! Imagine that we have a square with sides of length 2 and a unit circle
+//! (radius = 1), both centered at the origin. The areas are:
+//!
+//! ```text
+//! area of circle = πr² = π * r * r = π
+//! area of square = 2² = 4
+//! ```
+//!
+//! The circle is entirely within the square, 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.
+
+#![cfg(feature="std")]
+
+
+extern crate rand;
+
+use rand::distributions::{Distribution, Uniform};
+
+fn main() {
+ let range = Uniform::new(-1.0f64, 1.0);
+ let mut rng = rand::thread_rng();
+
+ let total = 1_000_000;
+ let mut in_circle = 0;
+
+ for _ in 0..total {
+ let a = range.sample(&mut rng);
+ let b = range.sample(&mut rng);
+ if a*a + b*b <= 1.0 {
+ in_circle += 1;
+ }
+ }
+
+ // prints something close to 3.14159...
+ println!("π is approximately {}", 4. * (in_circle as f64) / (total as f64));
+}
diff --git a/rand/examples/monty-hall.rs b/rand/examples/monty-hall.rs
new file mode 100644
index 0000000..0932c5e
--- /dev/null
+++ b/rand/examples/monty-hall.rs
@@ -0,0 +1,116 @@
+// Copyright 2018 Developers of the Rand project.
+// Copyright 2013-2018 The Rust Project Developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! ## 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]: https://en.wikipedia.org/wiki/Monty_Hall_problem
+
+#![cfg(feature="std")]
+
+
+extern crate rand;
+
+use rand::Rng;
+use rand::distributions::{Distribution, Uniform};
+
+struct SimulationResult {
+ win: bool,
+ switch: bool,
+}
+
+// Run a single simulation of the Monty Hall problem.
+fn simulate<R: Rng>(random_door: &Uniform<u32>, rng: &mut R)
+ -> SimulationResult {
+ let car = random_door.sample(rng);
+
+ // This is our initial choice
+ let mut choice = random_door.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 }
+}
+
+// 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: u32, choice: u32, rng: &mut R) -> u32 {
+ use rand::seq::SliceRandom;
+ *free_doors(&[car, choice]).choose(rng).unwrap()
+}
+
+// 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: u32, open: u32) -> u32 {
+ free_doors(&[choice, open])[0]
+}
+
+fn free_doors(blocked: &[u32]) -> Vec<u32> {
+ (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 = Uniform::new(0u32, 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);
+}