Worked solutions — Probability & Discrete Distributions
Full numeric and conceptual answers to every Day 1 exercise. Each answer lays out the underlying logic, and — wherever the result is numeric — the R code that verifies it. Where a problem has a recurring sticking point, a "What to look for" note flags what to watch for in student work.
Exercise 1 — Boy-or-girl paradox
Sample space: {BB, BG, GB, GG}, each with probability 1/4.
(a) Condition on "at least one girl": 3 of 4 outcomes survive. Only GG = both girls. So $P = 1/3$.
(b) Condition on "older is a girl": 2 of 4 outcomes survive ({GB, GG}). Only GG. So $P = 1/2$.
(c) The two conditioning events are different. The second is strictly stronger (more specific), shrinking the sample space more.
set.seed(1)
fams <- matrix(sample(c("B","G"), 2*1e6, replace=TRUE), ncol=2)
mean(rowSums(fams=="G")==2) / mean(rowSums(fams=="G")>=1) # ~ 0.333
mean(fams[,1]=="G" & fams[,2]=="G") / mean(fams[,1]=="G") # ~ 0.500
Key idea
What to look for: students should explicitly state the sample space and which subset survives each conditioning. The "1/2 vs 1/3" confusion is normal — the aim is to make sure students can write out the sample-space restriction.Exercise 2 — Taxi / Bayes
Let $B$ = blue taxi (prior 0.01), $W_B$ = witness says blue.
(0.99*0.01) / (0.99*0.01 + 0.05*0.99) # 0.1667
Interpretation: only ~17% chance the taxi really was blue — base-rate dominance.
Key idea
What to look for: correctly identifying the false-positive rate as P(W_B | not B) = 0.05, not 1 − 0.99. Students often plug in the wrong "reliability" number.Exercise 3 — Tallest among neighbors
Define $X_i = 1$ if person $i$ is shorter than both neighbors. The indicator approach:
For any three distinct people, the smallest is in the "middle" with probability 1/3 — by symmetry of orderings, the middle is equally likely to be smallest, middle, or largest among the three. So $E[X] = n/3$.
n <- 50; reps <- 1e5
samples <- replicate(reps, {
h <- sample(n)
sum(h < c(h[n], h[-n]) & h < c(h[-1], h[1]))
})
mean(samples) # ~ 16.67
Key idea
What to look for: the indicator-variable trick. Many students try to compute the joint distribution and get stuck.Exercise 4 — Cystic fibrosis (basic)
(a) $P(\text{unaffected child}) = 1 - 1/4 = 3/4$.
(b) $P(\text{four unaffected}) = (3/4)^4 = 81/256 \approx 0.3164$.
(3/4)^4 # 0.3164
dbinom(0, 4, 0.25) # P(0 affected) = same number
Exercise 5 — Poisson vs Negative Binomial
Set λ = 10, simulate 1000 draws per distribution:
library(dplyr); library(tidyr); library(ggplot2)
set.seed(2025); n <- 1000; lambda <- 10
sims <- tibble(
pois = rpois(n, lambda),
nb_k5 = rnbinom(n, mu=lambda, size=5),
nb_k1 = rnbinom(n, mu=lambda, size=1),
nb_kp5= rnbinom(n, mu=lambda, size=0.5))
sims %>% summarise(across(everything(),
list(mean=mean, var=var, p0=~mean(.==0), pgt20=~mean(.>20))))
| Distribution | Mean (≈) | Variance (≈) | P(0) | P(>20) |
|---|---|---|---|---|
| Pois(10) | 10.0 | 10 | 0.000 | 0.002 |
| NB(10, k=5) | 10.0 | 30 | 0.004 | 0.046 |
| NB(10, k=1) | 10.0 | 110 | 0.091 | 0.135 |
| NB(10, k=0.5) | 10.0 | 210 | 0.218 | 0.155 |
(d) Many-zero, occasional-large data is the NB k=0.5 pattern.
Key idea
What to look for: students saying "Poisson has to have variance = mean" and connecting that to the failure mode in real data.Exercise 6 — Marten survival
dbinom(0:5, 5, 0.7)
# 0.00243 0.02835 0.13230 0.30870 0.36015 0.16807
This is Bin(5, 0.7). Mode at $k=4$ (rounding $(n+1)p = 4.2$ down). Mean = 3.5, variance = $5 \cdot 0.7 \cdot 0.3 = 1.05$.
Exercise 7 — CWD surveillance
(a) $Y \sim \text{Bin}(24, 0.12)$.
dbinom(3, 24, 0.12) # 0.2387
pbinom(4, 24, 0.12) # 0.8471
dbinom(0, 24, 0.12) # 0.0465
(d) The 4.65% chance of zero detections despite 12% prevalence is the critical surveillance message: sampling too few animals fails to certify "free of disease" even when present. Real-world surveillance programs use this exact calculation to set minimum sample sizes for declarations of freedom from disease.
Exercise 8 — Elk multinomial
p <- c(0.20, 0.45, 0.25, 0.10)
dmultinom(c(18, 38, 18, 6), prob=p) # 0.00117
set.seed(1)
flights <- rmultinom(5000, size=80, prob=p)
hist(flights[3,], main="Calves observed", xlab="count")
mean(flights[3,]) # ~ 20 (= 80 * 0.25)
var(flights[3,]) # ~ 15 (= 80*0.25*0.75)
(c) Each marginal of a multinomial is binomial: calves ~ Bin(80, 0.25).
Exercise 9 — Likert simulation
p <- c(.30, .20, .15, .20, .15)
rmultinom(1, 80, p)
sims <- rmultinom(500, 80, p)
mean(sims[5,]); sd(sims[5,]) # ~ 12 and ~ 3.2
The standard deviation across replicate surveys (~3) is large relative to the point estimate (~12), illustrating the noise in a single n=80 survey.
Exercise 10 — Cystic fibrosis generalized
$K \sim \text{Bin}(n, 0.25)$.
(b) $P(K \ge 1) = 1 - (0.75)^5 = 1 - 0.2373 = 0.7627$.
(c) Smallest $n$ with $P(\ge 1) \ge 0.5$ is $n = 3$ (since $0.75^3 = 0.4219 < 0.5$ — meaning $P(\ge 1) = 1 - 0.4219 = 0.578$).
1 - dbinom(0, 5, 0.25) # 0.7627
which(1 - dbinom(0, 1:10, 0.25) >= 0.5)[1] # 3
Stretch 11 — Sum of Bernoullis = Binomial
(a) Linearity of expectation: $E[\sum Y_i] = \sum p = np$.
(b) Under independence, $\mathrm{Var}(\sum Y_i) = \sum \mathrm{Var}(Y_i) = np(1-p)$.
(c) Linearity of expectation does NOT require independence. Variance addition does. The covariance terms $2\sum_{i<j} \mathrm{Cov}(Y_i, Y_j)$ vanish only under independence. Positive correlation inflates variance — overdispersion.
Stretch 12 — Binomial → Poisson limit
Set $p = \lambda/n$. Then
The three pieces:
- $\binom{n}{k}\left(\frac{\lambda}{n}\right)^k = \frac{n(n-1)\dots(n-k+1)}{k!\, n^k} \lambda^k \to \frac{\lambda^k}{k!}$ as $n \to \infty$.
- $(1-\lambda/n)^n \to e^{-\lambda}$.
- $(1-\lambda/n)^{-k} \to 1$.
Product: $\frac{\lambda^k e^{-\lambda}}{k!}$, the Poisson PMF.
Every case below holds $np = 4$ fixed while $n$ grows. The mean is pinned at 4 throughout; the variance is what moves:
# Exact variances: Binomial is np(1-p), Poisson is lambda
20*0.2*0.8 # 3.20
100*0.04*0.96 # 3.84
1000*0.004*0.996 # 3.984
# Pois(4) # 4.00
set.seed(1)
for(pp in list(c(20,0.2), c(100,0.04), c(1000,0.004))) {
x <- rbinom(1e4, pp[1], pp[2])
cat("n=", pp[1], " mean=", mean(x), " var=", var(x), "\n")
}
y <- rpois(1e4, 4); cat("Pois mean=", mean(y), " var=", var(y), "\n")
# n= 20 mean= 4.0015 var= 3.256023
# n= 100 mean= 4.0021 var= 3.825078
# n= 1000 mean= 3.9707 var= 3.917433
# Pois mean= 4.0035 var= 3.993687
The Binomial variance $np(1-p) = \lambda(1-p)$ is always short of the Poisson variance $\lambda$ by exactly the factor $(1-p)$. That is the whole story: Bin(20, 0.2) has variance 3.20, a full 20% below 4, and a histogram visibly narrower than Pois(4). Push $p$ down to 0.04 and the shortfall is 4%; at $p = 0.004$ it is 0.4%. The Poisson is the limit reached only as $p \to 0$ with $\lambda = np$ held fixed — so the distributions are not interchangeable at $n = 20$, and become so only as $n$ grows.
The PMFs tell the same story. Comparing each Binomial to Pois(4) over $k = 0, \dots, 15$, the largest absolute difference in probability is:
k <- 0:15
max(abs(dbinom(k, 20, 0.2) - dpois(k, 4))) # 0.0228
max(abs(dbinom(k, 100, 0.04) - dpois(k, 4))) # 0.0040
max(abs(dbinom(k, 1000, 0.004) - dpois(k, 4))) # 0.00039
The error is $O(p) = O(\lambda/n)$, so asymptotically each tenfold increase in $n$ should buy a tenfold reduction in the gap. Watch the two steps separately: $0.02283 / 0.004022 = 5.7$, but $0.004022 / 0.0003918 = 10.3$. The second step delivers the promised factor of ten; the first only manages 5.7. The reason is that the $O(p)$ rate is an asymptotic statement, and $p = 0.2$ is not small — $n = 20$ is not yet in the regime where the rate applies. That is exactly why Bin(20, 0.2) is the case that shows you the approximation has to be earned.
Key idea
What to look for: students should notice that the mean is fixed at 4 by construction and therefore carries no information about convergence — the variance is the diagnostic. A student who reports "they all look the same" has not looked at $n = 20$.Stretch 13 — Monty Hall (camera trap)
P(initial guess right) = 1/3 regardless of what is revealed. The technician's reveal of an empty camera moves the remaining 2/3 onto the unopened alternative. So switch.
The simulation has to actually model the technician and the switch — otherwise it just restates the analytic claim. Draw the truth and the guess, let the technician open a camera that is neither, then switch to whatever is left:
set.seed(1)
trials <- 1e5
truth <- sample(1:3, trials, replace=TRUE) # camera holding the marten
guess <- sample(1:3, trials, replace=TRUE) # your initial pick
# Technician opens a camera that is neither your pick nor the marten's
opened <- vapply(seq_len(trials), function(i) {
choices <- setdiff(1:3, c(guess[i], truth[i]))
if (length(choices) == 1) choices else sample(choices, 1)
}, numeric(1))
# You switch to the one remaining unopened camera
switched <- vapply(seq_len(trials), function(i) {
setdiff(1:3, c(guess[i], opened[i]))
}, numeric(1))
mean(guess == truth) # stay wins: 0.33257
mean(switched == truth) # switch wins: 0.66743
Real output: staying wins 0.33257 of 100,000 trials, switching wins 0.66743 — matching 1/3 and 2/3.
Key idea
What to look for: the simulation must contain a host who is constrained to open a losing, non-chosen camera. A student whose code fixesguess <- 1 and reports mean(truth != guess) has computed P(initial guess wrong) by construction — it returns 2/3 whether or not switching is a good idea, so it verifies nothing.