Skip to content

Instantly share code, notes, and snippets.

@gorayni
Last active March 14, 2021 22:09
Show Gist options
  • Save gorayni/08b5bc780e68c5820072d7a51e825559 to your computer and use it in GitHub Desktop.
Save gorayni/08b5bc780e68c5820072d7a51e825559 to your computer and use it in GitHub Desktop.
Twiddle algorithm by Phillip J Chase, `Algorithm 382: Combinations of M out of N Objects [G6]', Communications of the Association for Computing Machinery 13:6:368 (1970). Code based on Matthew Belmonte [http://www.netlib.no/netlib/toms/382].
import numpy as np
def twiddle(p, x=None, y=None, z=None):
j = np.argmax(p[1:]>0)+1
if p[j-1] == 0:
i = j-1
while i != 1:
p[i] = -1
i -= 1
p[j], p[1] = 0, 1
return (0,j-1,0,False)
if j>1:
p[j-1] = 0
j+=1
while p[j] > 0:
j+=1
i, k = j, j-1
while p[i] == 0:
p[i] = -1
i+=1
if p[i] == -1:
p[i] = p[k]
z = p[k]-1
p[k] = -1
return (i-1,k-1,z,False)
elif i != p[0]:
p[j] = p[i]
z = p[i]-1
p[i] = 0
return (j-1,i-1,z,False)
return (x,y,z,True)
def init_twiddle(m, n):
p = np.zeros((n+2),dtype=int)
p[0] = n+1
p[n-m+1:n+1] = np.arange(1,m+1)
p[n+1] = -2
if m == 0:
p[1] = 1
return p
N = 5
M = 2
b = np.zeros((N),dtype=int)
b[N-M:] = 1
i = 0
print i, b
p = init_twiddle(M, N)
x, y, z, done = twiddle(p)
while not done:
i +=1
b[x], b[y] = 1, 0
print(i, b)
x, y, z, done = twiddle(p, x, y, z)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment