fork download
  1. import random, collections
  2.  
  3. SAMPLES = 100000
  4. OUTPUT_PERIOD = 100000
  5. PRECISION = 8
  6.  
  7. ranks = ['A','T','K','Q','J','9']
  8. suits = ['C','D','H','S']
  9. cards = [(r,s) for r in ranks for s in suits]*2
  10.  
  11. def findMinRankOfSuit(cardCount, suit):
  12. """Return the minimum number of any rank in the specified suit."""
  13. minCount = 40
  14. for r in ranks[:-1]:
  15. if cardCount[(r,suit)] == 0:
  16. # There are no runs in this suit because a card is missing
  17. return 0
  18. minCount = min(cardCount[(r,suit)], minCount)
  19. return minCount
  20.  
  21.  
  22. def typeOfRun(cardCount):
  23. """Return 0 if there are no runs, 1 if the largest run is a single, ... 4 if
  24. the hand is a quad-run."""
  25. largestRun = 0
  26. for s in suits:
  27. typeOfRunInSuit = findMinRankOfSuit(cardCount, s)
  28. largestRun = max(typeOfRunInSuit, largestRun)
  29. return largestRun
  30.  
  31.  
  32. def findTypeOfMarriageInSuit(cardCount, suit):
  33. """Return the number of marriages in the given suit."""
  34. return min(cardCount[('K',suit)], cardCount[('Q',suit)])
  35.  
  36.  
  37. def typeOfMarriage(cardCount):
  38. """Return 0 if there are no marriages, 1 if the largest marriage is a
  39. single, ... 4 if the hand contains a quad-marriage."""
  40. largestMarriage = 0
  41. for s in suits:
  42. typeOfMarriageInSuit = findTypeOfMarriageInSuit(cardCount, s)
  43. largestMarriage = max(typeOfMarriageInSuit, largestMarriage)
  44. return largestMarriage
  45.  
  46.  
  47. def typeOfPinochle(cardCount):
  48. """Return 0 if there are no marriages, 1 if the largest marriage is a
  49. single, ... 4 if the hand contains a quad-marriage."""
  50. return min(cardCount[('J','D')], cardCount[('Q','S')])
  51.  
  52.  
  53. def typeOfAceAround(cardCount):
  54. """Return 0 if there are no ace arounds, 1 if the largest ace around is a
  55. single, ... 4 if the hand contains a quad-ace around."""
  56. minAround = 4
  57. for s in suits:
  58. minAround = min(cardCount[('A',s)], minAround)
  59. return minAround
  60.  
  61.  
  62. def typeOfRoundhouse(cardCount):
  63. """Return the number of roundhouses (marriage in each suit)."""
  64. smallestMarriage = 4
  65. for s in suits:
  66. typeOfMarriageInSuit = findTypeOfMarriageInSuit(cardCount, s)
  67. smallestMarriage = min(typeOfMarriageInSuit, smallestMarriage)
  68. return smallestMarriage
  69.  
  70.  
  71. def displayHeader():
  72. types = ['NONE', 'SINGLE', 'DOUBLE', 'TRIPLE', 'QUAD']
  73. probabilityHeadingFormat = '{:^'+str(PRECISION+2)+'}'
  74. stringFormat = '| MELD TYPE | ' + ' | '.join([probabilityHeadingFormat]*5) + ' |'
  75. print stringFormat.format(*types)
  76.  
  77.  
  78. def display(label, count):
  79. values = [label] + [count[i] / float(SAMPLES) for i in range(4+1)]
  80. probabilityFormat = '{:0.'+str(PRECISION)+'f}'
  81. stringFormat = '| {:<11} | ' + ' | '.join([probabilityFormat]*5) + ' |'
  82. print stringFormat.format(*values)
  83.  
  84. runCount = collections.defaultdict(int)
  85. marriageCount = collections.defaultdict(int)
  86. pinochleCount = collections.defaultdict(int)
  87. aceAroundCount = collections.defaultdict(int)
  88. roundhouseCount = collections.defaultdict(int)
  89.  
  90. for i in xrange(SAMPLES):
  91. random.shuffle(cards)
  92. hand = cards[:12]
  93. cardCount = collections.defaultdict(int)
  94. for h in hand:
  95. cardCount[h] += 1
  96. runCount[typeOfRun(cardCount)] += 1
  97. marriageCount[typeOfMarriage(cardCount)] += 1
  98. pinochleCount[typeOfPinochle(cardCount)] += 1
  99. aceAroundCount[typeOfAceAround(cardCount)] += 1
  100. roundhouseCount[typeOfRoundhouse(cardCount)] += 1
  101.  
  102. if i % OUTPUT_PERIOD == OUTPUT_PERIOD - 1:
  103. print i / OUTPUT_PERIOD
  104. print 'R: ', [float(runCount[j]) / i for j in range(4+1)]
  105. print 'M: ', [float(marriageCount[j]) / i for j in range(4+1)]
  106. print 'P: ', [float(pinochleCount[j]) / i for j in range(4+1)]
  107. print 'A: ', [float(aceAroundCount[j]) / i for j in range(4+1)]
  108. print 'H: ', [float(roundhouseCount[j]) / i for j in range(4+1)]
  109.  
  110. print
  111. displayHeader()
  112. display('Runs', runCount)
  113. display('Marriages', marriageCount)
  114. display('Pinochles', pinochleCount)
  115. display('Ace Arounds', aceAroundCount)
  116. display('Roundhouses', roundhouseCount)
  117.  
  118.  
  119. # Output from 100,000 runs:
  120. #| MELD TYPE | NONE | SINGLE | DOUBLE | TRIPLE | QUAD |
  121. #| Runs | 0.96159000 | 0.03841000 | 0.00000000 | 0.00000000 | 0.00000000 |
  122. #| Marriages | 0.41159000 | 0.57792000 | 0.01049000 | 0.00000000 | 0.00000000 |
  123. #| Pinochles | 0.81545000 | 0.18201000 | 0.00254000 | 0.00000000 | 0.00000000 |
  124. #| Ace Arounds | 0.97317000 | 0.02683000 | 0.00000000 | 0.00000000 | 0.00000000 |
  125. #| Roundhouses | 0.99976000 | 0.00024000 | 0.00000000 | 0.00000000 | 0.00000000 |
  126.  
Time limit exceeded #stdin #stdout 5s 10080KB
stdin
Standard input is empty
stdout
Standard output is empty