Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Jun 16th, 2012  |  syntax: Python  |  size: 3.64 KB  |  views: 147  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #!/usr/bin/env python
  2.  
  3. from math import log10, floor
  4. from datetime import datetime
  5. import sys
  6.  
  7. def round_sig(x, sig=2):
  8.     return round(x, sig-int(floor(log10(x)))-1)
  9.  
  10. def factorial(n):
  11.     if n >= 1:
  12.         a = 1
  13.         for i in range(2,n+1):
  14.             a *= i
  15.         return a
  16.     else:
  17.         return 1
  18.  
  19. def choose(n,r):
  20.     return factorial(n) / (factorial(r)*factorial(n-r))
  21.  
  22. def nextDistribution():
  23.     global s1,s2,s3,s,h,d,c,dc
  24.     if s1<s2:
  25.         s1+=1
  26.     elif s2<s3:
  27.         s1=0
  28.         s2+=1
  29.     else:
  30.         s1=s2=0
  31.         s3+=1
  32.     s=s1
  33.     h=s2-s1
  34.     d=s3-s2
  35.     c=13-s3
  36.  
  37. def nextHonours():
  38.     global sh,hh,dh,ch,s,h,d,c,hflag
  39.     if sh < 3 and sh < s:
  40.         sh+=1
  41.     elif hh < 3 and hh < h:
  42.         sh=0
  43.         hh+=1
  44.     elif dh < 3 and dh < d:
  45.         sh=0
  46.         hh=0
  47.         dh+=1
  48.     elif ch < 3 and ch < c:
  49.         sh=0
  50.         hh=0
  51.         dh=0
  52.         ch+=1
  53.     elif ch == 3 or ch == c:
  54.         hflag = 1
  55.  
  56. def countLosers():
  57.     a=0
  58.     if (s<=3):
  59.         a+=s-sh
  60.     else:
  61.         a+=3-sh
  62.     if (h<=3):
  63.         a+=h-hh
  64.     else:
  65.         a+=3-hh
  66.     if (d<=3):
  67.         a+=d-dh
  68.     else:
  69.         a+=3-dh
  70.     if (c<=3):
  71.         a+=c-ch
  72.     else:
  73.         a+=3-ch
  74.     return a
  75.  
  76. def countDistributions():
  77.     global dc,sh,hh,dh,ch,s,h,d,c,ltc,dctotal
  78.     dc = choose(10,s-sh)*choose(10,h-hh)*choose(10,d-dh)*choose(10,c-ch)*choose(3,sh)*choose(3,hh)*choose(3,dh)*choose(3,ch)
  79.     ltc[countLosers()]+=dc
  80.     dctotal+=dc
  81.  
  82. def printDistribution():
  83.     global s,h,d,c,dc
  84.     print "|"+"-"*s+"*"+"-"*h+"*"+"-"*d+"*"+"-"*c+"|", dc
  85.  
  86. s1 = 0 # position between spades and hearts
  87. s2 = 0 # position between hearts and diamonds
  88. s3 = 0 # position between diamonds and clubs
  89.  
  90. s = 0 # number of spades in hand
  91. h = 0 # number of hearts in hand
  92. d = 0 # number of diamonds in hand
  93. c = 13 # number of clubs in hand
  94.  
  95. sh = 0 # number of spades honours in hand
  96. hh = 0 # number of hearts honours in hand
  97. dh = 0 # number of diamonds honours in hand
  98. ch = 0 # number of clubs honours in hand
  99.  
  100. ltc = [0,0,0,0,0,0,0,0,0,0,0,0,0] # number of hands with [n] losing tricks
  101.  
  102. hflag = 0 # flag to signal when all possible honour configurations for a distribution have been processed
  103.  
  104. dc = 0 # number of hands with the current distribution
  105.  
  106. dctotal = 0 # total number of hands
  107.  
  108. startTime = datetime.now()
  109.  
  110. visual = 0
  111. if "-v" in sys.argv:
  112.     visual = 1
  113.  
  114. for i in range(0,560): # repeat through all of the 560 possible distributions
  115.     while hflag==0: # if there are still honour configurations to process, continue the loop
  116.         countDistributions() # count losers, and add the number of hands with this distribution and honour configuration to the appopriate slot of ltc
  117.         nextHonours() # go to the next honour configuration
  118.     hflag = 0 # reset honours flag
  119.     sh = 0 # reset honours
  120.     hh = 0
  121.     dh = 0
  122.     ch = 0
  123.     if visual:
  124.         print (u'\x1b[35m|'+u'\u2588 '*int(i/28)+"  "*(19-int(i/28))+u'\b|\x1b[0m '+str(int(i/5.6)) + "% " + str(datetime.now()-startTime))
  125.         for i in range(0,13):
  126.             print str(ltc[i])+" hands with "+str(i)+" losing tricks: "+str(round(100*float(ltc[i])/float(dctotal),4))+"%"
  127.         print str(dctotal)+" hands in total"
  128.         print "\r\x1b[16A"
  129.     nextDistribution() # go to the next hand distribution
  130.  
  131. completionTime = datetime.now()-startTime
  132. if visual:
  133.     print (u'\r\x1b[35m|'+u'\u2588 '*19+u'\b|\x1b[0m '+str(100) + "% " + str(completionTime))
  134. for i in range(0,13):
  135.     print str(ltc[i])+" hands with "+str(i)+" losing tricks: "+str(round(100*float(ltc[i])/float(dctotal),4))+"%"
  136. print str(dctotal)+" hands in total"
clone this paste RAW Paste Data