Last week, you used the sample function to simulate random phenomena that had a finite sample space with equally-likely outcomes: coin flips, die rolls, playing cards. Using a loop, you repeated an experiment many many times, calculated the proportion of the time some event happened, and used that proportion as an approximation of the probability1. In class this week, we learned counting techniques for actually doing the math to compute these probabilities exactly.
In this lab, you will do both of these things, the math and the simulation, and verify that they agree. The examples today are small potatoes, but these generic skills are important. Being able to whip up computer simulations of random systems is one of the main skills that will empower you to continue self-studying probability and statistics after you leave the classroom. Hardly a day goes by when myself and my colleagues don’t run a simulation of some kind.
Write-up instructions
The template for this assignment is in the Canvas files. You will submit solutions for Tasks 1 - 3 below (Task 0 is just an extra example for you to refer to). A complete solution has three pieces:
the R code that runs the simulation and approximates the probability;
the one line of code that uses R as a calculator to compute the exact decimal probability based on your mathematical solution;
A little math formula (between double dollar signs in your .qmd) that summarizes the final answer.
Tasks 0 and 1 below provide a model for how this looks: simulation, calculation, formula for \(P(A)\).
Now let’s see how the math goes. The complement of the target event “at least one ace” is “no aces at all.” This is simpler and may be easier to count, so we will apply:
\[
P(A)=1-P(A^c)=1-\frac{\#(A^c)}{\#(S)}.
\]
The sample space \(S\) is the set of all five-card hands you could be dealt. We are selecting \(k=5\) from \(n=52\) without replacement and ignoring order, so \(\#(S)=\binom{52}{5}\). The event \(A^c\) is the set of all five-card hands that do not include an ace. There are 48 non-ace cards, and so \(\#(A^c)=\binom{48}{5}\). As such
In order to do the math, we apply \(P(A)=\#(A)/\#(S)\) directly. The sample space \(S\) is the set of all three-dice rolls. Thought of as three experiments in the sense of the counting principle, the number of ways we could mix and match the rolls is \(\#(S)=6\times6\times6=6^3=216\). The target event \(A\) is the set of all three-dice rolls where all numbers are different (ie sampling without replacement), and so \(\#(A)=6\times 5\times 4=120\). Putting it into R gives:
Scenario: you randomly place 8 rooks on distinct squares of a chess board;
Event: all 8 rooks are safe from one another.
Figure 1 displays an example of a safe position. In chess, rooks are permitted to move up-and-down or side-to-side as far as they want, but not diagonally or anything else.
This code creates a matrix representing the chess board, from which you can sample the random positions:
Here’s an example of 8 random squares chosen for the rooks:
random_position
[1] "g6" "h4" "h6" "f4" "d1" "c6" "d7" "d6"
So that’s where your 8 rooks live. In order to check whether or not they are safe from one another, you might find it helpful to separate out the row information and the column information of the placement using the substring command:
board<-outer(letters[1:8], 1:8, paste0)set.seed(2025)nsim<-100000count_safe<-0for(iin1:nsim){rooks<-sample(board, 8)# split into rows (numbers) and cols (letters)r<-substring(rooks, 2, 2)# row = the number partc<-substring(rooks, 1, 1)# col = the letter part# safe if all 8 rows are different AND all 8 cols are differentif(length(unique(r))==8&length(unique(c))==8){count_safe<-count_safe+1}}count_safe/nsim
[1] 1e-05
Recall that rooks can move up and down or side-to-side, but not diagonally. In order to be safe from one another, two rooks therefore need to occupy different rows and columns of the board. For the eight rooks to be mutually safe, they all must be in different columns and different rows from one another;
There are \(n=8\cdot 8=64\) squares on the board, and we are selecting \(k=8\) of them at which to place the rooks. The rooks are identical, so order doesn’t matter, and it’s without replacement since the squares need to be distinct, and so the total number of possible outcomes is \(\#(S)=\binom{64}{8}\);
The event \(A\) we care about is “the rooks are safe from one another,” and this can happen \(\#(A)=8!\) ways.
We know that a safe placement will have every row and column occupied by exactly one rook, so let us imagine building up a safe placement row-wise, starting from the bottom and working upward. There are 8 ways to place a single rook on the bottom row. No other rooks can go there, so we move to the next row. There are only 7 ways to place the next rook in the next row, because we must avoid the column occupied by the first rook. Similarly, there are only 6 ways to place the next rook in the next row, because we must avoid the two columns occupied by the first two rooks. And so on. As a consequence of the counting principle, where we regard each row as an experiment, we see that \(\#(A)=8\times7\times6\times\cdots\times2\times1=8!\).