### TWO PAIRS VERSUS THREE OF A KIND ### # A hand of cards is 'two pairs' if there are two cards of one kind, two cards # of a different kind, and a fifth card of a still-different kind. For example, # 5H 5S JS JD QS is two pairs. # A hand of cards is 'three of a kind' if there are three cards of one kind, a # fourth card of a different kind, and a fifth card of a still-different kind. # For example, KC KS KD 3S 2S is three of a kind. # Which one is rarer? The answer matters to poker players, because the rarer # one beats the more common one. # We could compute the exact probabilities. In fact, computing them is good # practice for you. But we could instead simulate a bunch of randomly chosen # hands, and simply count how often we get two pairs or three of a kind. In # general, simulation lets us check our exact answers, and it gives us # approximate answers, when exact answers are too difficult to compute. # Let's agree that cards are simply numbers between 1 and 52. The first 13 # numbers are A, 2, ..., K of spades. Then come the hearts, then the diamonds, # then the clubs. A hand is a vector of five distinct cards. # This function, whenever you invoke it, produces a random hand. (You are not # supposed to understand how this code works.) randomHand <- function() { sample(1:52, 5, replace=FALSE) } # This function, when you give it a hand, gives you back a sorted list of the # kinds in that hand (with repetition). The possible kinds range from 1 (A) to # 13 (K). handKinds <- function(hand) { sort((hand - 1) %% 13 + 1) } # This function tests whether a given hand's kinds are two pairs. isTwoPairs <- function(kinds) { if (kinds[[1]] == kinds[[3]] || kinds[[3]] == kinds[[5]] || kinds[[5]] == kinds[[1]]) { # There are not three distinct kinds in the hand. FALSE } else if (kinds[[1]] == kinds[[2]] && kinds[[3]] == kinds[[4]]) { # The hand looks like pair, pair, other. TRUE } else if (kinds[[1]] == kinds[[2]] && kinds[[4]] == kinds[[5]]) { # The hand looks like pair, other, pair. TRUE } else if (kinds[[2]] == kinds[[3]] && kinds[[4]] == kinds[[5]]) { # The hand looks like other, pair, pair. TRUE } else FALSE } # This function tests whether a given hand's kinds are three of a kind. isThreeOfAKind <- function(kinds) { if (kinds[[1]] == kinds[[2]] && kinds[[2]] == kinds[[3]] && kinds[[1]] != kinds[[4]] && kinds[[4]] != kinds[[5]] && kinds[[5]] != kinds[[1]]) { # This hand looks like three, other, another. TRUE } else if (kinds[[2]] == kinds[[3]] && kinds[[3]] == kinds[[4]] && kinds[[1]] != kinds[[2]] && kinds[[2]] != kinds[[5]] && kinds[[5]] != kinds[[1]]) { # This hand looks like other, three, another. TRUE } else if (kinds[[3]] == kinds[[4]] && kinds[[4]] == kinds[[5]] && kinds[[1]] != kinds[[2]] && kinds[[2]] != kinds[[3]] && kinds[[3]] != kinds[[1]]) { # This hand looks like other, another, three. TRUE } else FALSE } # Here are some pointed tests. kinds <- c(2, 2, 5, 5, 8) isTwoPairs(kinds) isThreeOfAKind(kinds) kinds <- c(4, 4, 4, 7, 9) isTwoPairs(kinds) isThreeOfAKind(kinds) kinds <- c(10, 10, 10, 10, 11) isTwoPairs(kinds) isThreeOfAKind(kinds) kinds <- c(9, 9, 9, 12, 12) isTwoPairs(kinds) isThreeOfAKind(kinds) # Here is a random test. If you run this chunk of code repeatedly, then you # start to get an idea for how common two pairs and three of a kind are. hand <- randomHand() hand kinds <- handKinds(hand) kinds isTwoPairs(kinds) isThreeOfAKind(kinds) # This chunk of code automates the random repetitions. Try increasing # numTrials, if you're willing to spend more time to (probably) get more # accurate results. numTrials <- 1000000 numTwoPairs <- 0 numThreeOfAKind <- 0 for (k in 1:numTrials) { kinds <- handKinds(randomHand()) if (isTwoPairs(kinds)) numTwoPairs <- numTwoPairs + 1 if (isThreeOfAKind(kinds)) numThreeOfAKind <- numThreeOfAKind + 1 } numTwoPairs / numTrials numThreeOfAKind / numTrials # How well do these simulation results match the probabilities that you compute # by hand? ### POWERBALL ### # PowerBall is a lottery that runs in most parts of the USA. There are 10 # levels of prizes, with the highest prize being a jackpot, whose value varies # over time. Here are the prizes in dollars, with a jackpot that you can set # yourself. jackpot <- 20000000 payouts <- c(0, 4, 4, 7, 7, 100, 100, 50000, 1000000, jackpot) payouts # Here are the probabilities of winning each of those payouts. (In reality, # when multiple players win the jackpot, they split it. For simplicity, we # pretend that each jackpot winner wins the entire jackpot.) probs <- 1 / c(1.041901, 38.32, 91.98, 701.33, 579.76, 14494.11, 36525.17, 913129.18, 1168805352, 292201338) probs # How much does PowerBall pay, on average? One way to estimate the answer is to # simulate a bunch of plays and average the results. Again, try increasing # numPlays if you want more accurate results. numPlays <- 100000000 mean(sample(payouts, numPlays, replace=TRUE, prob=probs)) # Soon in the course we will learn a way to calculate the average payout # exactly and quickly. sum(payouts * probs) # By the way, a PowerBall ticket costs $2.