Check out the Pastebin Gadgets Shop. We have thousands of fun, geeky & affordable gadgets on sale :-)Want more features on Pastebin? Sign Up, it's FREE!
tweet

# Untitled

By: a guest on Jun 16th, 2012  |  syntax: Python  |  size: 3.64 KB  |  views: 211  |  expires: Never
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
Top