Calculating a magic square

5

I'm trying to make a magic square:

  • A magic square is one that is divided into rows and columns, with a number in each position and the sum of rows, columns, and diagonals is the same.
  • Example (3x3 - no. 1 to 9):

    8   3   4 
    
    1   5   9 
    
    6   7   2
    

I tried to use a 3x3 array and a vector with 9 indices.

import random
                #j(coluna)
matriz = [[1, 2, 3],#i(linha)
          [4, 5, 6],
          [7, 8, 9]]
res = False
#DEFINIR UMA FUNÇÃO PARA CALCULAR AS SOMAS DE TODOS OS LADOS
def magicsquare():
    if matriz[0][0] + matriz[1][0] + matriz[2][0] == matriz[0][1] + matriz[1][1] + matriz[2][1] == matriz[0][2] + matriz[1][2] + matriz[2][2] == matriz[0][0] + matriz[0][1] + matriz[0][2] == matriz[1][0] + matriz[1][1] + matriz[1][2] == matriz[2][0] + matriz[2][1] + matriz[2][2] == matriz[0][0] + matriz[1][1] + matriz[2][2] == matriz[0][2] + matriz[1][1] + matriz[2][0]:
        return res == True
    else:
        return res == False

#DEFINIR UM LOOP PARA GERAR Nº ALEAT. ATÉ ENCONTRAR OS QUE SATIZFAZEM
#AS CONDIÇÕES DE UM QUADRADO MÁGICO
seq = [1, 2, 3, 4, 5, 6, 7, 8, 9]
while res == False:
    for i in range(2):
        for j in range(2):
            z = random.choice(seq)
            matriz[i][j] = z
            x = seq.index(z)
            seq[x] = []
    magicsquare()
print (matriz)
#---------------------------------------------------------------------------------------------------------------------------------------------------------------
res = False
def magicsquare():
    if vetor[0] + vetor[1] + vetor[2] == vetor[3] + vetor[4] + vetor[5] == vetor[6] + vetor[7] + vetor[8] == vetor[0] + vetor[3] + vetor[6] == vetor[1] + vetor[4] + vetor[7] == vetor[2] + vetor[5] + vetor[8] == vetor[0] + vetor[4] + vetor[8] == vetor[2] + vetor[4] + vetor[6]:
        return res == True
    else:
        return res == False
#        0  1  2  3  4  5  6  7  8
vetor = [1, 2, 3, 4, 5, 6, 7, 8, 9]
seq = [1, 2, 3, 4, 5, 6, 7, 8, 9]
if res == False:
    for i in range(8):
        w = random.choice(seq)
        #Repor o valor w(1 a 9) no index i(0 a 8). Sem usar valores e indexes repetidos
        vetor.insert(i, w)
        #Eliminar os valores já utilizados
        x = seq.index(w)
        seq[x] =[]
    magicsquare()
print (vetor)

The result is always: [1, 2, 3, 4, 5, 6, 7, 8, 9]

Can anyone help me build a magic square?

Using Python 3.5.0

    
asked by anonymous 21.11.2015 / 19:00

1 answer

5
  

I will answer based on your first attempt, with array, because logic is simpler

First, your logic to check whether an array satisfies or not the magic square condition is correct. The problem with this function is that it is returning the inverse result, and doing so in an obscure way. I suggest - especially if you're a beginner in programming - avoid assigning a value and using it at the same time as this is a potential source of errors.

In addition, there is one extra detail: you expect the magicsquare function to affect the res variable set outside of it. To ensure this, it is best to declare it as global , so that the function does not create a new copy of it (I'm not sure exactly what the rule is, but I had this problem here).

def magicsquare():
    global res
    if matriz[0][0] + matriz[1][0] + matriz[2][0] == matriz[0][1] + matriz[1][1] + matriz[2][1] == matriz[0][2] + matriz[1][2] + matriz[2][2] == matriz[0][0] + matriz[0][1] + matriz[0][2] == matriz[1][0] + matriz[1][1] + matriz[1][2] == matriz[2][0] + matriz[2][1] + matriz[2][2] == matriz[0][0] + matriz[1][1] + matriz[2][2] == matriz[0][2] + matriz[1][1] + matriz[2][0]:
        res = True  # Primeiro atribui...
    else:
        res = False # Primeiro atribui...
    return res # ...depois usa

Second, you're trying to "erase" the already-drawn values from the seq set so that they are not re-drawn. The problem is that you are doing this simply by assigning a new value to it:

seq[x] = []

What not only does not prevent it from being drawn again, it also introduces a new possibility: to have [] as an element of your magic square! And the worst is this: if the first attempt is not valid, it will never hit again, because the value has been deleted and has not been restored.

A correct way to do this would be to actually remove the element from the set (so that it can not be drawn again) and - at the beginning of the new loop - restoring its set to the initial state so that it can try again :

while res == False:
    seq = [1, 2, 3, 4, 5, 6, 7, 8, 9] # Dentro do while, não fora
    for i in range(3): # 3, não 2 (0,1,2)
        for j in range(3):
            z = random.choice(seq)
            matriz[i][j] = z
            x = seq.index(z)
            seq = seq[:x] + seq[x+1:] # Remove o elemento x do conjunto
    magicsquare()

Example running on ideone

    
21.11.2015 / 21:33