def sjt_local(pi, inv, x): # The goal of local(pi, inv, i) is to move i permutation pi with inverse # permutation inv in the direction of until it hits a "barrier", defined as # an element greater than it. d = -1 while True: y = pi[inv[x] + d] # y is the element next to x in direction d if x < y: d = -d # Switch direction yield False else: transpose(pi, inv, x, y) yield True
def gen_all(n): # Pad on both sides to allow for a natural stop pi = [n + 1] + list(range(1, n + 1)) + [n + 1] inv = pi[:] # Keep track of directions, all starting negative (move left) d = [-1] * (n + 2) x = n # x is the active element yield pi[1:-1] while x > 0: y = pi[inv[x] + d[x]] # y is the element next to x in direction d[x] if x < y: d[x] = -d[x] # Switch direction x -= 1 # Change active element to x - 1 else: transpose(pi, inv, x, y) yield pi[1:-1] # New permutation is generated x = n # Change active element to n
def pruesse_ruskey_product(poset, pi, inv, X, a, b): Y_ab = pruesse_ruskey_local(poset, pi, inv, a, b) Y_ba = pruesse_ruskey_local(poset, pi, inv, b, a) while True: for result in Y_ab: if not result: break yield result for result in X: if not result: break if result is SWITCH_SIGN: transpose(pi, inv, a, b) Y_ab, Y_ba = Y_ba, Y_ab yield True for result in Y_ab: if not result: break yield result yield False