\documentclass[notitlepage]{article} \usepackage{../Math323} \usepackage{listings} \usepackage{numprint} \usepackage{enumerate} \usepackage{bbm} \usepackage{amsfonts,amsmath} \setlength{\parindent}{0pt} \def\E{\Expect} \lstloadlanguages{R} \definecolor{keywordcolor}{rgb}{0,0.6,0.6} \definecolor{delimcolor}{rgb}{0.461,0.039,0.102} \definecolor{Rcommentcolor}{rgb}{0.101,0.043,0.432} \lstdefinestyle{Rsettings}{ basicstyle=\ttfamily, breaklines=true, showstringspaces=false, keywords={if, else, function, theFunction, tmp}, % Write as many keywords otherkeywords={}, commentstyle=\itshape\color{Rcommentcolor}, keywordstyle=\color{keywordcolor}, moredelim=[s][\color{delimcolor}]{"}{"}, } \lstset{basicstyle=\ttfamily, numbers=none, literate={~} {$\sim$}{2}} \begin{document} <>= library(knitr) # global chunk options opts_chunk$set(cache=TRUE, autodep=TRUE) options(scipen=999) options(repos=c(CRAN="https://cloud.r-project.org/")) @ \begin{center} \textsclarge{MATH 323: Probability} \medskip {\textsclarge{Combinatorial Probability: Poker Hands}} \end{center} We have the table of probabilities for poker hands as follows: recall that the `scoring' cards are denoted $x$ and $y$, the other cards are denoted $a$, $b$ etc. The denominator in the probability calculation is \[ n_S = \dbinom{52}{5}. \] The probabilities can be computed in \texttt{R} using the \texttt{choose} function: <>= nS<-choose(52,5) n1<-choose(13,1)*choose(4,2)*choose(12,3)*choose(4,1)^3 n2<-choose(13,2)*choose(4,2)^2*choose(11,1)*choose(4,1) n3<-choose(13,1)*choose(4,3)*choose(12,2)*choose(4,1)^2 n4<-choose(10,1)*choose(4,1)^5-choose(10,1)*choose(4,1) n5<-choose(13,5)*choose(4,1)-choose(10,1)*choose(4,1) n6<-choose(13,1)*choose(4,3)*choose(12,1)*choose(4,2) n7<-choose(13,1)*choose(4,4)*choose(12,1)*choose(4,1) n8<-10*choose(4,1)-choose(4,1) n9<-choose(4,1) n0<-nS-(n1+n2+n3+n4+n5+n6+n7+n8+n9) round(c(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9)/nS,7) Probs<-c(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9)/nS @ \begin{table}[h] \begin{center} \begin{tabular}{lllll} Hand & Configuration & \multicolumn{1}{c}{$n_A$} & Prob. \\ \hline \\ ONE PAIR & ~~$xxabc$~~ & $\displaystyle{{13 \choose 1}{4 \choose 2} \times {12 \choose 3}{4 \choose 1}{4 \choose 1}{4 \choose 1}}$ & \Sexpr{round(n1/nS,7)} \\ \\[-1.5ex] TWO PAIRS & ~~$xxyya$~~ & $\displaystyle{{13 \choose 2}{4 \choose 2}{4 \choose 2} \times {11 \choose 1}{4 \choose 1}}$ & \Sexpr{round(n2/nS,7)}\\ \\[-1.5ex] THREE OF A KIND & ~~$xxxab$~~ & $\displaystyle{{13 \choose 1}{4 \choose 3} \times {12 \choose 2}{4 \choose 1}{4 \choose 1}}$ & \Sexpr{round(n3/nS,7)} \\ \\[-1.5ex] STRAIGHT & ~~Run of five cards~~ & $ \displaystyle{{10 \choose 1}{4 \choose 1}^5} -\displaystyle{{10 \choose 1}{4 \choose 1}}$ & \Sexpr{round(n4/nS,7)} \\ \\[-1.5ex] FLUSH & ~~Five cards in same suit~~& $\displaystyle{{13 \choose 5}{4 \choose 1}} -\displaystyle{{10 \choose 1}{4 \choose 1}}$ & \Sexpr{round(n5/nS,7)} \\ \\[-1.5ex] FULL HOUSE & ~~$xxxyy$~~ & $\displaystyle{{13 \choose 1}{4 \choose 3} \times {12 \choose 1}{4 \choose 2}}$ & \Sexpr{round(n6/nS,7)} \\ \\[-1.5ex] FOUR OF A KIND & ~~$xxxxa$~~ & $\displaystyle{{13 \choose 1}{4 \choose 4} \times {12 \choose 1}{4 \choose 1}}$ & \Sexpr{round(n7/nS,7)}\\ \\[-1.5ex] STRAIGHT FLUSH & ~~Run of five cards in same suit~~& $~~~~~ \displaystyle{{10 \choose 1}} \displaystyle{{4 \choose 1}} - \displaystyle{{4 \choose 1}} $ & \Sexpr{round(n8/nS,7)} \\ \\[-1.5ex] ROYAL FLUSH & ~~AKQJ10 in any suit~~& ~~~~~ $1 \displaystyle{{4 \choose 1}}$ & \Sexpr{round(n9/nS,7)} \end{tabular} \caption{Probabilities for different poker hands. For STRAIGHT and FLUSH, we must remember to subtract the STRAIGHT FLUSHes (which are counted separately); similarly, for STRAIGHT FLUSH, must remember to subtract ROYAL FLUSHes.} \end{center} \end{table} \pagebreak We can attempt to check these numbers using a simulation in the computer package \texttt{R}. For example, if we identify the numbers $\{1,2,3,\ldots,52\}$ with the cards in a pack listed suit-wise (Hearts, Clubs, Diamonds, Spades) and within a suit, denomination-wise, so that \[ 1 = \textrm{`Two of Hearts'} \qquad 2 = \textrm{`Three of Hearts'} \qquad \cdots \qquad 12 = \textrm{`King of Hearts'} \qquad 13 = \textrm{`Ace of Hearts'} \] then \[ 14 = \textrm{`Two of Clubs'} \qquad 15 = \textrm{`Three of Clubs'} \qquad \cdots \qquad 25 = \textrm{`King of Clubs'} \qquad 26 = \textrm{`Ace of Clubs'} \] etc., we can simulate a hand of give cards using the \texttt{sample} function. Thus the suit is decided by assessing which quartile of the range the selected number lies, and the denomination is decided by writing the selected number modulo 13 (and following the convention that 13 mod 13 = 13, unlike the usual rule in modulo arithmetic). \medskip A small simulated example is as follows: <>= set.seed(2101) #Set the random number generator seed value suit.names<-c('H','C','D','S') denomination.names<-c(as.character(2:10),'J','Q','K','A') suit.list<-rep(suit.names,each=13) denomination.list<-rep(denomination.names,4) selected.hand<-sample(1:52,size=5) denomination<-denomination.list[selected.hand] suit<-suit.list[selected.hand] denomination;suit @ Thus the hand drawn is \[ (\texttt{9 of Spades, Queen of Spades, 9 of Clubs, 4 of Diamonds, King of Diamonds}) \] which is a PAIR (two nines). To decide upon which hand has been dealt, we need to carry out some basic manipulations and calculations. <>= denomination.count<-rep(0,52) denomination.count[selected.hand]<-1 denomination.count<-apply(matrix(denomination.count,nrow=13,ncol=4),1,sum) if(max(denomination.count) == 4){ print('4 of a kind !') }else if(max(denomination.count) == 3){ if(max(denomination.count[denomination.count != 3]) == 2){ print('Full house !') }else{ print('3 of a kind !') } }else if(max(denomination.count) == 2){ if(sum(denomination.count == 2) == 2){ print('Two pairs !') }else{ print('Pair !') } }else if(max(table(suit)) == 5){ denom.vals<-(selected.hand %% 13) denom.vals[denom.vals==0]<-13 print(denom.vals) if(max(denom.vals)-min(denom.vals) == 4){ if(max(denom.vals) == 13){ print('Royal Flush !') }else{ print('Straight Flush !') } }else{ print('Flush !') } }else{ denom.vals<-(selected.hand %% 13) denom.vals[denom.vals==0]<-13 if(max(denom.vals)-min(denom.vals) == 4){ print('Straight !') } } @ This series of calculations return the result that the simulated hand is a \texttt{Pair}. \medskip We can check the computed probabilities from the table by carrying out a large simulation study, drawing 10 million hands, say, and counting up the number of occurrences of each hand type. First, we can write a small function in \texttt{R} to take a simulated hand and determine what the hand type is. <>= hand.type<-function(selected.hand){ denomination<-denomination.list[selected.hand] suit<-suit.list[selected.hand] denomination.count<-rep(0,52) denomination.count[selected.hand]<-1 denomination.count<-apply(matrix(denomination.count,nrow=13,ncol=4),1,sum) hand.type<-0 if(max(denomination.count) == 4){ #print('4 of a kind !') hand.type<-7 }else if(max(denomination.count) == 3){ if(max(denomination.count[denomination.count != 3]) == 2){ #print('Full house !') hand.type<-6 }else{ #print('3 of a kind !') hand.type<-3 } }else if(max(denomination.count) == 2){ if(sum(denomination.count == 2) == 2){ #print('Two pairs !') hand.type<-2 }else{ #print('Pair !') hand.type<-1 } }else if(max(table(suit)) == 5){ denom.vals<-(selected.hand %% 13) denom.vals[denom.vals==0]<-13 if(max(denom.vals)-min(denom.vals) == 4){ if(max(denom.vals) == 13){ #print('Royal Flush !') hand.type<-9 }else{ #print('Straight Flush !') hand.type<-8 } }else{ #print('Flush !') hand.type<-5 } }else{ denom.vals<-(selected.hand %% 13) denom.vals[denom.vals==0]<-13 if(max(denom.vals)-min(denom.vals) == 4){ #print('Straight !') hand.type<-4 } } return(hand.type) } Nsamp<-1000000 sample.hands<-t(replicate(Nsamp,sample(1:52,size=5))) hand.totals<-apply(sample.hands,1,hand.type) hand.totals<-tabulate(hand.totals+1,nbins=10) simulated.probs<-hand.totals/Nsamp @ Here is a summary of the simulation results: <>= Hands<-c('Null','Pair','Two Pairs','Three of a Kind','Straight','Flush', 'Full House','Four of a Kind','Straight Flush','Royal Flush') #hand.totals<-c(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9) data.frame(Hands,Expected=round(Nsamp*Probs),Simulated=hand.totals, TrueProb=Probs,EstimatedProb=simulated.probs) @ \end{document}