[心得] 撲克與排列組合

看板Mathematica作者 (Hysterisis)時間10年前 (2014/04/10 18:05), 10年前編輯推噓1(100)
留言1則, 1人參與, 最新討論串1/1
撲克牌13支(外國多稱為Chinese Poker)當中,顧名思義手牌有13張 分為3,5,5張的三墩。 牌品為:高牌、一對、兩對、三條、順子、同花、葫蘆、鐵支、同花順 其中有些 特殊牌型 如 六對子 (ex. AA 22 33 44 55 55 K)、三同花(同花)、三順子 前兩個並不需要用到Mathematica,就能算出來共有幾種組合,機率多少 只要用 Wolfram Alpha 線上計算就可以了 例如六對半 考慮有 k 個鐵支的狀況,總組合有 Σ C(13,k)*C(13-k,6-2k)*C(4,2)^(6-2k)*(52-12), {k,0,3} = 3 542 247 280 (ps當然,會把三鐵支當六對半的人是瘋子,但排列組合,數學上來講這樣更簡單) 還有三同花 C(4,3)*3*C(13,5)^2*C(13,3) + C(4,2)*2*C(13,8)*C(13,5) + C(4,2)*2*C(13,10)*C(13,3) + 4 = 5 705 516 392 (ps各項依序為[三種花色] + [兩種花色為5張8張] + [兩種花色為3張10張] + [理論上 也能算三同花的一條清龍] ) 三順子就比較難算了,可能性較多,就要藉程式輔助 Total[Times @@@ ((Tally /@ (Tuples[{Range[11], Range[10], Range[10]}] /. {x1_, x2_, x3_} :> (Flatten[{Range[x1, x1 + 2], Range[x2, x2 + 4], Range[x3, x3 + 4]}]/. 14->1 ))) /. {_, n_} :> Binomial[4, n])] 一行碼,基本精神:反正每個數字有四張,三個順子重疊沒關係 首個順子可以從 (123) 到 (JQK),11取1。後兩個可以從(12345) 到 (TJQKA),10取1。 所以用Tuple取出像 {1, 10, 3} 這種數列 把它轉換成順子所需的牌 {{1,2,3}, {10,11,12,13,1}, {3,4,5,6,7}} 然後每種數字選擇花色,有k張的方法是 C(4,k) 全部相乘,加總。 得到 4 662 122 240 種 目前小結: 六對半 3542247280 種,機率0.56% 三同花 5705516392 種,機率0.90% 三順子 4662122240 種,機率0.73% 與超好的牌相反,有些牌型你拿到會怨嘆今天到底該說今天運氣太好還是運氣太差 例如 「超爛兩對子」,恰兩對,卻沒有順子,也沒有同花 這可能嗎?只要恰好斷在 5 與 10,其餘中兩個是對子、其餘各一張即可 如 A22 33467 89JQK。 (斷在5與10是只有兩對的唯一一種可能,簡單可驗證。) 已經完成兩個條件了,「沒有同花」怎麼排? 這裡介紹 IntegerPartitions 函數 IntegerPartitions[13, {4}, {0,1,2,3,4}] │ │ 可以使用的數,小於5,要是5張就同花了 │ 分成幾個數 被分的數 = {{4, 4, 4, 1}, {4, 4, 3, 2}, {4, 3, 3, 3}} 結果證明把0加進去是多餘的 這就是可能的花色張數(分別有4,12,4種排列),這其實用手就算得出來XD 然後,要把 A22 33467 89JQK 分進去......嗎?別傻了不用真的分 以 {4,4,3,2} 為例,我們有兩個對子 22 33,同數字花色必須不同 於是必須做從{4,4,3,2} 挑兩個數減1,共做兩次這個動作 令gp={{1,1,0,0},{1,0,1,0},{1,0,0,1},{0,1,1,0},{0,1,0,1},{0,0,1,1}} 第一次減 Flatten[ Outer[Subtract, {{4,4,3,2}}, gp, 1 ],1] 這裡有鋪梗 這個1有學問,他是指定深度1,也就是將 {1,1,0,0}這樣的括號(向量) 當一個物件 非要不可,否則會被MMA解讀成神奇的高 維度張量運算。 第二次減 Flatten[ Outer[Subtract, % , gp, 1 ],1] 沒錯梗在於公式完全一樣,不用再打一次^^ 會跑出 {{2,2,3,2},{2,3,2,2},{2,3,3,1},{3,2,2,2},{3,2,3,1},{3,3,2,1},{2,3,2,2}, {2,4,1,2},{2,4,2,1},{3,3,1,2},{3,3,2,1},{3,4,1,1},{2,3,3,1},{2,4,2,1}, {2,4,3,0},{3,3,2,1},{3,3,3,0},{3,4,2,0},{3,2,2,2},{3,3,1,2},{3,3,2,1}, {4,2,1,2},{4,2,2,1},{4,3,1,1},{3,2,3,1},{3,3,2,1},{3,3,3,0},{4,2,2,1}, {4,2,3,0},{4,3,2,0},{3,3,2,1},{3,4,1,1},{3,4,2,0},{4,3,1,1},{4,3,2,0}, {4,4,1,0}} 這個時候表示,第一種情形,我們要把剩下的九張相異牌 (即 A 4 6789 JQK) 分派花色是 2桃 2心 3磚 2梅,分法有 9!/ (2!2!3!2!) 種 這時介紹另一個好用函數 Multinomial,他就是上述的計算 因此總和為 Total[Multinomial@@@{{2,2,3,2},{2,3,2,2}, ... ,{4,4,1,0}}] =142590 我們討論的花色數組是 {4,4,3,2},因此須乘以 12 但是有陷阱,當選花色數是 {4,4,4,1} 時,必須改成 Flatten[ Outer[Subtract, {{4,4,4,1}}, gp, 1 ],1] /. {___, _?(#<0&), ___}->Sequence[] 這是因為減第二次時,選到不能減(該套花色張數用完),則出現負數 不過恰好只要把這些數組移除,剩下就是可行的數組。 這個算法的方便是其實只要這樣就能得到完整的答案 suit=Flatten[ Permutations/@{{4,4,4,1}, {4,4,3,2}, {4,3,3,3}}, 1]; Flatten[ Outer[Subtract, suit, gp, 1 ],1]/. {___, _?(#<0&), ___}->Sequence[] Flatten[ Outer[Subtract, %, gp, 1 ],1]/. {___, _?(#<0&), ___}->Sequence[] Total[Multinomial@@@%]*Binomial[11,2] (*11號碼選2成對*) 答案是 152 044 200 種,機率0.024%,或約四千分之一。 比六對半還少見,應該成立一個牌品的XD 有趣的是,多出來的兩張如果是同一數字, 會變成罕見5倍,微妙的強一點點的牌「除了一個三條,什麼都沒有」 XDDD 例如 A22234 6789 JQK = = = = 終章 練習: 這種 "牌品" 有幾種組合 「恰好三對,順子同花什麼的完全沒有↖」 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.112.213.88 ※ 文章網址: http://www.ptt.cc/bbs/Mathematica/M.1397124358.A.83B.html 附一個簡短的判斷牌組有沒有順子的函數 x={1,1,2,3,4,5,5,7,8,9,10,10} y=Sort@DeleteDuplicates@x (*{1,2,3,4,5,7,8,9,10}*) isStr[y_]:= Or[ And @@ (MemberQ[x, #] & /@ {1, 10, 11, 12, 13}), (*AK順當例外*) MatchQ[Differences[x], {___, Repeated[1, {4}], ___}]] (*←這怎麼??*)

04/10 19:51, , 1F
補充: 中間的 gp 可由 Permutations[{1,1,0,0}] 求出
04/10 19:51, 1F
啊XDDD ※ 編輯: jurian0101 (140.112.213.88), 04/11/2014 11:39:01
文章代碼(AID): #1JHcq6Wx (Mathematica)
文章代碼(AID): #1JHcq6Wx (Mathematica)