Riddler: Monte Carlo Simulation



December 3, 2018

Notable topics: Simulation

Recorded on: 2018-12-03

Timestamps by: Alex Cookson

View code




Using crossing function to set up structure of simulation (1,000 trials, each with 12 chess games)

Adding result to the tidy simulation dataset


Using sample function to simulate win/loss/draw for each game (good explanation of individual arguments within sample)


Using group_by and summarise to get total points for each trial

Adding red vertical reference line to histogram to know when a player wins a matchup

Answering second piece of riddle (how many games would need to be played for better player to win 90% or 99% of the time?)


Using unnest and seq_len function to create groups of number of games (20, 40, …, 100), each with one game per row

Creating a win field based on the simulated data, then summarising win percentage for each group of number of games (20, 40, …, 100)


Using seq function to create groups of number of games programmatically

Explanation of using logarithmic scale for this riddle

Changing spacing of number of games from even spacing (20, 40, …, 100) to exponential (doubles every time, 12, 24, 48, …, 1536)

Changing spacing of number of games to be finer

Introduction of interpolation as the last step we will do


Introducing approx function as method to linearly interpolate data

Break point for the next riddle

Starting recursive approach to this riddle


Setting up a N x N matrix (N = 4 to start)

Explanation of approach (random ball goes into random cup, represented by matrix)


Using sample function to pick a random element of the matrix

Using for loop to iterate random selection 100 times

Converting for loop to while loop, using colSums to keep track of number of balls in cups

Starting to code the pruning phase

Using diag function to pick matching matrix elements (e.g., the 4th row of the 4th column)

Turning code up to this point into a custom simulate_round function

Using custom simulate_round function to simulate 100 rounds


Using all function to perform logic check on whether all cups in a round are not empty

Converting loop approach to tidy approach


Using rerun and map_lgl functions from purrr package to simulate a round for each for in a dataframe

Explanation of the tidy approach


Using cumsum and lag functions to keep track of the number of rounds until you win a "game"

Creating histogram of number of rounds until winning a game

Setting boundary argument of geom_histogram function to include count of zeros

Brief explanation of geometric distribution

Extending custom simulate_round function to include number of balls thrown to win (in addition to whether we won a round)

Extending to two values of N (N = 3 or N = 4)

Reviewing results of N = 3 and N = 4

Extending to N = 5

Checking results of chess riddle with Riddler solution

Checking results of ball-cup riddle with Riddler solution (Dave slightly misinterpreted what the riddle was asking)

Changing simulation code to correct the misinterpretation

Reviewing results of corrected simulation

Checking results of ball-cup riddle with corrected simulation with Riddler solutions

Visualizing number of balls thrown and rounds played