-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathperms.py~
executable file
·68 lines (61 loc) · 2.15 KB
/
perms.py~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/python
import sys
def choose(n, k):
"""
A fast way to calculate binomial coefficients by Andrew Dalke (contrib).
(This probably isn't good for large values of n and k, but OK for our purposes --GH)
"""
if 0 <= k <= n:
ntok = 1
ktok = 1
for t in range(1, min(k, n - k) + 1):
ntok *= n
ktok *= t
n -= 1
return ntok // ktok
else:
return 0
def integer2coloring(y, a, m):
"""
Take an integer and convert it into a binary coloring
"""
if m < a or y > choose(m,a): # Check that we didn't give nonsense input
print "y=",y," m=",m," a=",a
sys.exit("bad call to integer2coloring")
# This follows the algorithm in the enum3 paper, Comp Mat Sci 59 101 (2010) exactly
I = y
t = a
ell = m
configlist = [-1]*m
#while any([i==-1 for i in configlist]):
while ell > 0:
if choose(ell-1,t-1) <= I:
configlist[m-ell] = 0
I -= choose(ell-1,t-1)
else:
configlist[m-ell] = 1
t -= 1
ell -= 1
return configlist
def coloring2integer(coloring):
"""
Take a coloring list and convert it into an integer
"""
m = len(coloring)
# Find the rightmost 1 in the list
coloring.reverse()
rm1 = m - coloring.index(1) # Finds the leftmost 1 (but we reversed the list)
coloring.reverse() # Put the list back in the correct order
z = coloring[:rm1].count(0) # Number of zeros with at least one "1" to their right
x = 0
templist = coloring
for i in range(z): # Loop over the zeros with a 1 to their right
p0 = templist.index(0) # Position of first zero in the temporary list
n1r = templist[p0:].count(1) # Number of 1s to the right of leftmost zero
templist = templist[p0+1:] # Throw away the leftmost zero
x += choose(len(templist),n1r-1) # Compute the binomial coefficient for this "digit" of the number
return x
### Test the routines for the case of 10 slots and 3 "red" (and 7 non-red)
for i in range(choose(10,3)):
l = integer2coloring(i,3,10)
print "%3d" % i,l, coloring2integer(l)