Reputation: 21
Input consists of several cases, each with the order n of a square, followed by n rows, each with n natural numbers between 1 and n². Like:
3
6 1 8
7 5 3
2 9 4
1
1
(...)
extra conditions:
should print ("yes") if its a magic square and ("no") if don't
so my code solves all correct inputs except the ones that have some number repeated, and I don't know how to solve that problem
my code
a = read(int)
while a is not None:
check1 = True
t = 0
s = 0
listaA = []
## create matrix of lists like A([b[],b[],b[]])
for j in range(a):
b = []
for k in range(a):
c = read(int)
if c in listaB:
(a-1) - k
listaB.append(c)
b.append(c)
listaA.append(b)
if a == 1:
check1 = False
print("yes")
else:
x = sum(listaA[0])
i=0
while i<a and check1 == True:
#for i in range(a):
# suma la primera fila
suma=sum(listaA[i])
if x != suma:
print('no')
break
## check columns
y = 0
for j in range(a):
y += listaA[j][i]
if y != x:
print('no')
break
i+=1
## check diagonals
if i==a:
for i in range(a):
t += (listaA[i][i])
s += listaA[i][(a-1)-i]
if s != x or t != x:
print('no')
else:
print('yes')
a = read(int)
some idea ???
Upvotes: 1
Views: 3482
Reputation: 106455
You can use a set comparison to check if all the numbers between 1 and n² appear once, and use sum
with generator expressions like this to test if all rows, columns and the two major diagonals sum the same:
def is_magic(m):
n = len(m)
s = (n ** 2 + 1) * n // 2
return (
set(range(1, n ** 2 + 1)) == set(i for r in m for i in r) and
all(sum(r) == s for r in (*m, *zip(*m))) and
sum(m[i][i] for i in range(n)) == sum(m[i][-i - 1] for i in range(n)) == s
)
so that:
is_magic(
[
[6, 1, 8],
[7, 5, 3],
[2, 9, 4]
]
)
returns:
True
Upvotes: 2