1

I'm new to coding. I'm trying to program a magic square. A magic square is a square (3 × 3 for my case, could be different), where all rows and columns and diagonals must sum to a certain number (15 for my case, because of the 3 × 3). Here is my code:

s = []
while len(s) < 9:
    n = 0
    a = random.randrange(1, 10)
    while a not in s:
        s.append(a)


while s[0] + s[1] + s[2] != 15 and s[3] + s[4] + s[5] != 15 and \
        s[6] + s[7] + s[8] != 15 and s[0] + s[4] + s[8] != 15 \
        and s[2] + s[4] + s[6] != 15 and s[0] + s[3] + s[6] != 15 and \
        s[1] + s[4] + s[7] != 15 and s[2] + s[5] + s[8] != 15:
    shuffle(s)
print(s)

I don't understand why the program isn't shuffling until all the criteria are met in the while loop. I know this is not the way to code this program and even if it would work, it would be randomness and brute forcing the solution, i would just like to understand what is happening inside the while loop.

Michael MacAskill
  • 2,411
  • 1
  • 16
  • 28
bucephalusII
  • 59
  • 1
  • 4

2 Answers2

3

I think you've written the condition of your loop incorrectly. It currently requires that none of the rows, columns or diagonals add up to the right value. If any of them do, it quits, since the chained ands result in a False value.

Instead, I think you want to use the or operator instead of the and operator. That way you'd keep looping as long as any of the conditions was true (meaning any of the lines didn't add up correctly).

Or alternatively, you could keep the and operators, but change the != operators to == and negate the whole thing at the end (since not X or not Y is logically equivalent to not (X and Y)):

while not (s[0] + s[1] + s[2] == 15 and s[3] + s[4] + s[5] == 15 and 
           s[6] + s[7] + s[8] == 15 and s[0] + s[4] + s[8] == 15 and
           s[2] + s[4] + s[6] == 15 and s[0] + s[3] + s[6] == 15 and
           s[1] + s[4] + s[7] == 15 and s[2] + s[5] + s[8] == 15):
Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • Thanks you very much, yes you are right, as soon as the first criteria is met, the while loop stops because it required all of the criteria to be met at the same time, but we just solved a criteria...so it didn't shuffle anymore. Thank you again! – bucephalusII Nov 18 '18 at 23:03
0

I think you mean to replace your 'ands' with 'ors'. The program is terminating as soon as the first condition is met because logically the way that you have written it all of those conditions need to be met for it to continue. Also, while not strictly necessary, I've generally found that the brackets around individual logic conditions tend to help.

s = []
while len(s) < 9:
    n = 0
    a = random.randrange(1, 10)
    while a not in s:
        s.append(a)


while (s[0] + s[1] + s[2] != 15) or (s[3] + s[4] + s[5] != 15) or \
    (s[6] + s[7] + s[8] != 15) or (s[0] + s[4] + s[8] != 15) \
    or (s[2] + s[4] + s[6] != 15) or (s[0] + s[3] + s[6] != 15) or \
    (s[1] + s[4] + s[7] != 15) or (s[2] + s[5] + s[8] != 15):
    shuffle(s)
print(s)
  • Please show an example of how it will with ORs as answers with no examples attract downvotes. – Shiko Nov 18 '18 at 22:56
  • Thank you so much, yes reading your comment i just realized as soon the first criteria is met it stops because then the while is not 'activated' anymore (1 criteria is missing) – bucephalusII Nov 18 '18 at 23:01