Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
First solution in Uncategorized category for Magic Square by chadheyne
import itertools
MAGIC_NUMBERS = dict((k, int(k*(k**2+1)/2)) for k in range(3, 15))
def checkio(data):
missing = [i for i in range(1, len(data)**2+1)
if not any(i in row for row in data)]
possible = {}
for i, row in enumerate(data):
possible[i] = [j for j in itertools.permutations(missing, row.count(0))
if sum(j) + sum(row) == MAGIC_NUMBERS[len(data)]]
for replace in itertools.product(*possible.values()):
check_magic = data[:]
for i, tup in enumerate(replace):
tup = iter(tup)
check_magic[i] = [j if j else next(tup) for j in data[i]]
if is_magic(len(data), check_magic):
return check_magic
return [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
def is_magic(size, square):
magic_number = MAGIC_NUMBERS[size]
flat = list(itertools.chain.from_iterable(square))
return (all(i in flat for i in range(1, size**2 + 1)) and
all(sum(i)==magic_number for i in [flat[i::size] for i in range(size)]) and
all(sum(i)==magic_number for i in square) and
sum(flat[::size+1]) == magic_number and
sum([row[size-1-i] for i, row in enumerate(square)]) == magic_number)
#These "asserts" using only for self-checking and not necessary for auto-testing
if __name__ == '__main__':
print(checkio([
[2, 7, 6],
[9, 5, 1],
[4, 3, 0]
]))
#must return [[2, 7, 6], [9, 5, 1], [4, 3, 8]]
print(checkio([
[0, 0, 0],
[0, 5, 0],
[0, 0, 0]
]))
#can return [[2, 7, 6], [9, 5, 1], [4, 3, 8]] or
# [[4, 9, 2], [3, 5, 7], [8, 1, 6]
print(checkio([[1, 15, 14, 4],
[12, 0, 0, 9],
[8, 0, 0, 5],
[13, 3, 2, 16]]))
# answer [[1, 15, 14, 4], [12, 6, 7, 9], [8, 10, 11, 5], [13, 3, 2, 16]]
Oct. 5, 2013
Comments: