Sep-19-2018, 09:49 PM
(This post was last modified: Sep-19-2018, 09:51 PM by Gribouillis.)
I would use two functions, the first one is
Here is the code:
unique_everseen()
defined in the documentation of module itertools. It removes duplicates from a sequence, or more precisely items that have a duplicate 'key' in a sequence, where the key can be any quantity computed from the items. The second function is normalize()
defined below. It takes a magic square and it transform it by using symetry in order to have the smallest corner in the north west and the smallest neighbor of the smallest corner on its east side. With this, two equivalent magic squares have the same normalized version and this normalized version is used as the key in unique_everseen().Here is the code:
def unique_everseen(iterable, key=None): "List unique elements, preserving order. Remember all elements ever seen." # unique_everseen('AAAABBBCCDAABBB') --> A B C D # unique_everseen('ABBCcAD', str.lower) --> A B C D seen = set() seen_add = seen.add if key is None: for element in filterfalse(seen.__contains__, iterable): seen_add(element) yield element else: for element in iterable: k = key(element) if k not in seen: seen_add(k) yield element def normalize(square): """Compute by symetry an equivalent magic square such that the smallest corner is in the north-west and the square on the east of the smallest corner is smaller than the square on the south of the smallest corner. """ square = tuple(tuple(row) for row in square) corner = square[0][0], square[0][-1], square[-1][-1], square[-1][0] i = corner.index(min(corner)) if i == 1: square = tuple(row[::-1] for row in square) elif i == 2: square = tuple(row[::-1] for row in square[::-1]) elif i == 3: square = square[::-1] if square[1][0] < square[0][1]: return tuple(zip(*square)) else: return square if __name__ == '__main__': A = [(2,7,6), (9,5,1), (4,3,8)] B = [(2,9,4), (7,5,3), (6,1,8)] C = [(2,11,5), (9,6,3), (7,1,10)] for square in unique_everseen([A, B, C], key=normalize): print(square)
Output:[(2, 7, 6), (9, 5, 1), (4, 3, 8)]
[(2, 11, 5), (9, 6, 3), (7, 1, 10)]