In [1]:
def binom(n, k):
if k < 0 or k > n:
return 0
return factorial(n)/(factorial(k)*factorial(n-k))
In [2]:
[[binom(n, k) for k in range(n+1)] for n in range(11)]
Out[2]:
In [3]:
def listBSnk(n, k):
if k > n:
return []
if k == 0:
return [n*[0]]
return ([[0]+x for x in listBSnk(n-1, k)] +
[[1]+x for x in listBSnk(n-1, k-1)])
In [4]:
listBSnk(5,2)
Out[4]:
In [5]:
def rankBSnk(n, k, x):
if n == 0:
if k == 0 and x == []:
return 0
else:
raise IndexError
if k == 0:
if len(x) == n and all(v == 0 for v in x):
return 0
else:
raise IndexError
assert k > 0 and n > 0
if x[0] == 0:
return rankBSnk(n-1, k, x[1:])
elif x[0] == 1:
return binom(n-1, k) + rankBSnk(n-1, k-1, x[1:])
else:
raise IndexError
In [6]:
rankBSnk(5,2,[0,1,0,0,1])
Out[6]:
In [7]:
N, K = 5, 5
[rankBSnk(N, K, v) for v in listBSnk(N, K)] == range(binom(N, K))
Out[7]:
In [8]:
def unrankBSnk(n, k, r):
if not 0 <= r < binom(n, k):
raise IndexError
if n == 0:
if k == 0 and r == 0:
return []
else:
raise IndexError
if k == 0:
if r == 0:
return [0]*n
else:
raise IndexError
reccount = binom(n-1, k)
if r < reccount:
return [0] + unrankBSnk(n-1, k, r)
else:
return [1] + unrankBSnk(n-1, k-1, r - reccount)
In [9]:
unrankBSnk(5, 2, 3)
Out[9]:
In [10]:
N, K = 6, 0
[unrankBSnk(N, K, r) for r in range(binom(N, K))] == listBSnk(N, K)
Out[10]:
In [11]:
N, K = 100, 50
r = randint(0, binom(N, K))
o = unrankBSnk(N, K, r)
rankBSnk(N, K, o) == r
Out[11]:
In [12]:
@cached_function
def binom(n, k):
if not 0 <= k <= n:
return 0
if k == 0:
return 1
else:
return binom(n-1, k) + binom(n-1, k-1)
In [13]:
[[binom(n, k) for k in range(n+1)] for n in range(11)]
Out[13]:
In [14]:
binom(100, 50)
Out[14]:
In [ ]: