Skip to content

Instantly share code, notes, and snippets.

@ashish0x90
Created November 22, 2010 19:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ashish0x90/710503 to your computer and use it in GitHub Desktop.
Save ashish0x90/710503 to your computer and use it in GitHub Desktop.
Code to generate nCk combinations for a n-length array (Won't work with sequences having duplicate values)
def prepArray(idxs,array):
return [array[x] for x in idxs] #This step is O(n) too
def combinations(array,k):
"""
Code to generate nCk combinations for a n-length array (Won't work with sequences having duplicate values)
Maybe not so effecient but my implementation, Don't know about algo implemented in standard library
Standard lib - itertools.combinations
Just Wrote code to pass the time. :)
Here is the idea:
I am keeping indexes in the k-length array - idxs, which follow the invariant that it is STRICTLY INCREASING.
Keeping that invariant in mind, I am generating the sequences in lexicographical increasing order.
Lets see if you can figure out the pattern from this pattern of idxs.
For , n = 6, k = 4 , *Idxs* are generated as follows.
[0, 1, 2, 4]
[0, 1, 2, 5]
[0, 1, 3, 4]
[0, 1, 3, 5]
[0, 1, 4, 5]
[0, 2, 3, 4]
[0, 2, 3, 5]
[0, 2, 4, 5]
[0, 3, 4, 5]
[1, 2, 3, 4]
[1, 2, 3, 5]
[1, 2, 4, 5]
[1, 3, 4, 5]
[2, 3, 4, 5]
"""
array = list(array)
yield array[:k]
idxs = range(k)
max_k = len(array)
while True:
while idxs[k-1] < max_k - 1:
idxs[k-1]+=1
yield prepArray(idxs,array)
a = k-2
while a >= 0:
if idxs[a] < a + (max_k - k):
idxs[a]+=1
idxs[a+1:] = range(idxs[a]+1, idxs[a]+1+ (k - a - 1)) #Maybe we can do better here, the step is O(n)
yield prepArray(idxs, array)
break
else:
a-=1
if a < 0:
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment