def morph(S, B): ''' Input: - S: a list of distinct Vecs - B: a list of linearly independent Vecs all in Span S Output: a list of pairs of vectors to inject and eject (see problem description) Example: >>> # This is how our morph works. Yours may yield different results. >>> # Note: Make a copy of S to modify instead of modifying S itself. >>> from vecutil import list2vec >>> from vec import Vec >>> S = [list2vec(v) for v in [[1,0,0],[0,1,0],[0,0,1]]] >>> B = [list2vec(v) for v in [[1,1,0],[0,1,1],[1,0,1]]] >>> D = {0, 1, 2} >>> morph(S, B) == [(Vec(D,{0: 1, 1: 1, 2: 0}), Vec(D,{0: 1, 1: 0, 2: 0})), (Vec(D,{0: 0, 1: 1, 2: 1}), Vec(D,{0: 0, 1: 1, 2: 0})), (Vec(D,{0: 1, 1: 0, 2: 1}), Vec(D,{0: 0, 1: 0, 2: 1}))] True >>> S == [list2vec(v) for v in [[1,0,0],[0,1,0],[0,0,1]]] True >>> B == [list2vec(v) for v in [[1,1,0],[0,1,1],[1,0,1]]] True >>> from GF2 import one >>> D = {0, 1, 2, 3, 4, 5, 6, 7} >>> S = [Vec(D,{1: one, 2: one, 3: one, 4: one}), Vec(D,{1: one, 3: one}), Vec(D,{0: one, 1: one, 3: one, 5: one, 6: one}), Vec(D,{3: one, 4: one}), Vec(D,{3: one, 5: one, 6: one})] >>> B = [Vec(D,{2: one, 4: one}), Vec(D,{0: one, 1: one, 2: one, 3: one, 4: one, 5: one, 6: one}), Vec(D,{0: one, 1: one, 2: one, 5: one, 6: one})] >>> sol = morph(S, B) >>> sol == [(B[0],S[0]), (B[1],S[2]), (B[2],S[3])] or sol == [(B[0],S[1]), (B[1],S[2]), (B[2],S[3])] True >>> # Should work the same regardless of order of S >>> from random import random >>> sol = morph(sorted(S, key=lambda x:random()), B) >>> sol == [(B[0],S[0]), (B[1],S[2]), (B[2],S[3])] or sol == [(B[0],S[1]), (B[1],S[2]), (B[2],S[3])] True ''' S0 = S.copy() A = set([]) pairs = [] for z in B: w = exchange(set(S0), A, z) # S0 = (S0 | {z}) - {w} S0.append(z) S0.remove(w) # A = A | {z} A = A | {z} pairs.append((z,w)) return pairs