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