知恵袋のカードの確率の問題をPythonで解いてみた。

 知恵袋のカードの確率の問題Pythonで解いてみました。元ネタは'99年のセンターテストのようです。(^_^;

 赤、青、緑、黄の4色のカードが5枚ずつ計20枚あり、各色のカードにはそれぞれ1から5までの番号が一つずつ書いてある。この20枚のカードの中から3枚を一度に取り出す。
(1)3枚がすべて同じ番号となる確率
(2)3枚が色も番号もすべて異なる確率
(3)3枚のうちに赤いカードがちょうど1枚含まれる確率
(4)3枚の中にある赤いカードの枚数の期待値

 拙ブログのTrump1.pyを雛形にしました。(^_^;
 カードに、0〜19の通し番号を与えると、5で割った商で色、5で割った余りからそれに1を加えてランク(番号)を得ることができます。

 sColor: ('R','B','Y','G')     = n: (0,1,2,3)   = (赤,青,黄,緑)
 sRank : ('1','2','3','4','5') = n: (0,1,2,3,4) = (1,2,3,4,5)

      0  1  2  3  4
      1  2  3  4  5: Rank
 0 R  0  1  2  3  4
 1 B  5  6  7  8  9
 2 Y 10 11 12 13 14
 3 G 15 16 17 18 19
 Color

 ちなみに、3枚がすべて同じ番号となる条件は、本来なら、 p%N+1==q%N+1==r%N+1ですが、全辺から1を引いて式を変形して、p%N==q%N==r%Nとしました。(ただし、N=5)
 また、この条件を別の方法で表して、len(set([p%N,q%N,r%N]))==1 としてもいいです。

● ColorCard1.py

# coding: UTF-8
# ColorCard1.py

import itertools
from time import time
from fractions import Fraction

COLOR = 'RBYG'
RANK  = '12345'
N = len(RANK)

# sColor: 'R','B','Y','G','K'
def countColor(sColor, lCards):
    li = [x//N for x in lCards]
    return li.count(COLOR.index(sColor))

def toStrCards(lCards):
    result = ''
    for c in lCards:
        result += ','+COLOR[c//N]+RANK[c%N]
    return '(' + result[1:] + ')'

def main():
    tm=time()  # Timer Start

    Cards = range(20)
    count = [0]*6
    total = 0
    for c in itertools.combinations(Cards,3):
        p,q,r = c
        total+=1
        if p%N==q%N==r%N: count[0]+=1
        if len(set([p%N,q%N,r%N]))==3 and len(set([p//N,q//N,r//N]))==3:
            count[1]+=1
        if countColor('R',c)==1: count[2]+=1
        if countColor('R',c)==2: count[3]+=1
        if countColor('R',c)==3: count[4]+=1
        # カードを表示
##        print(toStrCards(c))

    print("(1) %d/%d = %s"%(count[0],total,Fraction(count[0],total)))
    print("(2) %d/%d = %s"%(count[1],total,Fraction(count[1],total)))
    print("(3) %d/%d = %s"%(count[2],total,Fraction(count[2],total)))
    f1 = Fraction(count[2],total)
    f2 = Fraction(count[3],total)
    f3 = Fraction(count[4],total)
    fE = 1*f1+2*f2+3*f3
    print("(4) 1*%s+2*%s+3*%s = %s"%(f1,f2,f3,fE))
    print("Runtime : %.3f [sec]"%(time()-tm))   # Timer Stop & Disp

if __name__ == '__main__':
    main()

●実行結果

(1) 20/1140 = 1/57
(2) 240/1140 = 4/19
(3) 525/1140 = 35/76
(4) 1*35/76+2*5/38+3*1/114 = 3/4
Runtime : 0.015 [sec]

※参考URL
http://whs-math.net/math/sec2598.html
期待値の求め方(期待値の定義)
Python組み込みクラス(set 集合型)を使った論理式 - 今日のPython