Python Forum
python 3 and unique matrix
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
python 3 and unique matrix
#1
I have 3 magic squares like this:

2,7,6
9,5,1
4,3,8

(The Sum is: 15)
-----

2,9,4
7,5,3
6,1,8

(The Sum is: 15)

2,11,5
9,6,3
7,1,10

(The sum is: 18)

The firt two contain the same numbers in different positions and i would like to print only one of them in addition to square magic of sum 18.

I desire, in other words, to eliminate the matrix that uses the same number and to obtain:

2,7,6
9,5,1
4,3,8


2,11,5
9,6,3
7,1,10

With the list is used "set", with numpy array is used "np.unique", but what to use for the matrixes?

Thanks
Reply
#2
I would use two functions, the first one is 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)]
Reply
#3
Thanks Gribouillis. It's work
Reply
#4
Note that I suppose here that each number appears uniquely in a magic square. If you remove this assumption, you need to work more on the normalization procedure.
Reply
#5
Gribouillis, please be weary of accidentally doing someone's homework for them.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Python/C API Matrix to Numpy jibarra 0 1,849 Jul-29-2019, 03:25 PM
Last Post: jibarra

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020