Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- from math import log10, floor
- from datetime import datetime
- import sys
- def round_sig(x, sig=2):
- return round(x, sig-int(floor(log10(x)))-1)
- def factorial(n):
- if n >= 1:
- a = 1
- for i in range(2,n+1):
- a *= i
- return a
- else:
- return 1
- def choose(n,r):
- return factorial(n) / (factorial(r)*factorial(n-r))
- def nextDistribution():
- global s1,s2,s3,s,h,d,c,dc
- if s1<s2:
- s1+=1
- elif s2<s3:
- s1=0
- s2+=1
- else:
- s1=s2=0
- s3+=1
- s=s1
- h=s2-s1
- d=s3-s2
- c=13-s3
- def nextHonours():
- global sh,hh,dh,ch,s,h,d,c,hflag
- if sh < 3 and sh < s:
- sh+=1
- elif hh < 3 and hh < h:
- sh=0
- hh+=1
- elif dh < 3 and dh < d:
- sh=0
- hh=0
- dh+=1
- elif ch < 3 and ch < c:
- sh=0
- hh=0
- dh=0
- ch+=1
- elif ch == 3 or ch == c:
- hflag = 1
- def countLosers():
- a=0
- if (s<=3):
- a+=s-sh
- else:
- a+=3-sh
- if (h<=3):
- a+=h-hh
- else:
- a+=3-hh
- if (d<=3):
- a+=d-dh
- else:
- a+=3-dh
- if (c<=3):
- a+=c-ch
- else:
- a+=3-ch
- return a
- def countDistributions():
- global dc,sh,hh,dh,ch,s,h,d,c,ltc,dctotal
- 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)
- ltc[countLosers()]+=dc
- dctotal+=dc
- def printDistribution():
- global s,h,d,c,dc
- print "|"+"-"*s+"*"+"-"*h+"*"+"-"*d+"*"+"-"*c+"|", dc
- s1 = 0 # position between spades and hearts
- s2 = 0 # position between hearts and diamonds
- s3 = 0 # position between diamonds and clubs
- s = 0 # number of spades in hand
- h = 0 # number of hearts in hand
- d = 0 # number of diamonds in hand
- c = 13 # number of clubs in hand
- sh = 0 # number of spades honours in hand
- hh = 0 # number of hearts honours in hand
- dh = 0 # number of diamonds honours in hand
- ch = 0 # number of clubs honours in hand
- ltc = [0,0,0,0,0,0,0,0,0,0,0,0,0] # number of hands with [n] losing tricks
- hflag = 0 # flag to signal when all possible honour configurations for a distribution have been processed
- dc = 0 # number of hands with the current distribution
- dctotal = 0 # total number of hands
- startTime = datetime.now()
- visual = 0
- if "-v" in sys.argv:
- visual = 1
- for i in range(0,560): # repeat through all of the 560 possible distributions
- while hflag==0: # if there are still honour configurations to process, continue the loop
- countDistributions() # count losers, and add the number of hands with this distribution and honour configuration to the appopriate slot of ltc
- nextHonours() # go to the next honour configuration
- hflag = 0 # reset honours flag
- sh = 0 # reset honours
- hh = 0
- dh = 0
- ch = 0
- if visual:
- 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))
- for i in range(0,13):
- print str(ltc[i])+" hands with "+str(i)+" losing tricks: "+str(round(100*float(ltc[i])/float(dctotal),4))+"%"
- print str(dctotal)+" hands in total"
- print "\r\x1b[16A"
- nextDistribution() # go to the next hand distribution
- completionTime = datetime.now()-startTime
- if visual:
- print (u'\r\x1b[35m|'+u'\u2588 '*19+u'\b|\x1b[0m '+str(100) + "% " + str(completionTime))
- for i in range(0,13):
- print str(ltc[i])+" hands with "+str(i)+" losing tricks: "+str(round(100*float(ltc[i])/float(dctotal),4))+"%"
- print str(dctotal)+" hands in total"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement