Python – How do I convert a magic square to a suitable magic square in Python 3?

How do I convert a magic square to a suitable magic square in Python 3?… here is a solution to the problem.

How do I convert a magic square to a suitable magic square in Python 3?

I have such a magic square. The numbers in the Magic Square 3×3 can only be 1-9:

magic_square = [[5,3,4],
                [1,5,8],
                [6,4,2]]

I want to convert it to a proper 3×3 Rubik’s Cube with the sum of all rows, columns, and diagonals equal to 15 with the smallest changes possible.

I’ve tried permutation, but I can’t think of a way.

Solution

It’s not clear from the question what “change” is, but this code assumes that it means replacing a value in an array position with a different value. Another meaning is the number of exchanges required (which requires more code).

This code does something obvious: it generates all the magic squares (only one of them, at most reflection and rotation) and measures the distance to each magic square, finding the smallest one.

import itertools

def ms():
    rows = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]

for p in itertools.permutations(range(1, 10)):
        if all(sum(p[i] for i in r) == 15 for r in rows):
            yield list(p)

def closest_ms(m):
    m = sum(m, [])
    return min(ms(), key=(lambda x: sum(i!=j for i, j in zip(m, x))))

magic_square = [[5,3,4],
                [1,5,8],
                [6,4,2]]

print(closest_ms(magic_square))

The code returns the same magic square of 6 elements as the original:

8 3 4
1 5 9
6 7 2

Related Problems and Solutions