-3

I am trying to check if a two-dimensional array is a magic square. Getting confused about the interpretation of one or more of the directions below? I learn best by example so if anyone could show me directly with code I would appreciate it.

  • Write a function that accepts a two-dimensional list as an argument and determines whether the list is a Lo Shu Magic Square. Test the function in a program.

  • Your program should test the function with two different inputs, one qualifying as a magic square and another that doesn't qualify as a magic square. In each instance, the program should print the result of the function

def main():

    magicsquare = [[16, 2, 3, 13], [5, 11, 10, 8], [9, 7, 6, 12], [4, 14, 15, 1]]
    notmagicsquare = [[10, 7, 4, 5], [2, 1, 0, 8], [8, 4, 6, 1], [4, 4, 5, 1]]

    for r in range(rows):
        for c in range(columns):
            print(magicsquare)

    for r in range(rows):
        for c in range(columns):
            print(notmagicsquare)


main()
Daniel Hao
  • 4,922
  • 3
  • 10
  • 23
m24
  • 1
  • 4
  • what output you want? – codester_09 Jun 25 '22 at 11:19
  • @SharimIqbal I am looking to add the two dimensional list as an argument to the function and make sure my interpretation on having two inputs are correct. – m24 Jun 25 '22 at 11:25
  • you can edit your code with the output you want. – codester_09 Jun 25 '22 at 11:26
  • @SharimIqbal Do you have any advice on how to add the two dimensional list as function and how I would edit my code with that? – m24 Jun 25 '22 at 11:30
  • I may be wrong here but my understanding is that a Lo Shu Magic Square must have an odd number of cells along each edge i.e., not sure how you can have a 4x4 Lo Shu Magic Square – DarkKnight Jun 25 '22 at 12:17

3 Answers3

1

This works for me, try it and any questions - please ask.

Edit: also check the diagonal part. Thanks for @Albert points.

from typing import List

def check_magic(M: List[List[int]]) -> bool:
    for i in range(len(M)):        # whether the size of each row match the Matrix's?
       if len(M[i]) != len(M):
          return False

    N = sum(M[0])            # all rows, columns and diagonals   
    #  row sums check
    for row in M:
       if sum(row) != sum(M[0]):
          return False
    
    # column sums
    cols = [[r[c] for r in M] for c in range(len(M[0]))]

    for c in cols:
       if sum(c) != sum(M[0]):
          return False
       
    # check diagonal sums     # inspired by @Albert, credit to him
    d1 = d2 = 0 
    R = len(M)
    for i in range(R):
        d1 += M[i][i]
        d2 += M[~i][~i]
    
    return d1 == d2 == N


notmagic = [[10, 7, 4, 5],
            [2, 1, 0, 8],
            [8, 4, 6, 1],
            [4, 4, 5, 1]]



print(check_magic(notmagic))  # False
 
magic = [[16, 2, 3, 13],
         [5, 11, 10, 8],
         [9, 7,  6, 12],
         [4, 14, 15, 1]]

print(check_magic(magic))  # True
Daniel Hao
  • 4,922
  • 3
  • 10
  • 23
  • Hey thanks for replying here are my questions: 1. Is there anyway to make the more simple? 2. Could you please explain the first for loop? – m24 Jun 25 '22 at 12:24
  • 1
    @DanielHao Don't you need to check the sums of the diagonals? – DarkKnight Jun 25 '22 at 12:35
  • @m24 - not sure what's your mean by `making it more simple`? Maybe you can take this and try to `improve` further? – Daniel Hao Jun 25 '22 at 12:46
  • 1
    @DanielHao I will try thank you for contributing I really appreciate it – m24 Jun 25 '22 at 12:48
0

In a "magic" square the sum of each row, column and diagonal must be the same. In the context of a Python 2-dimensional list and bearing in mind that the lists in the 2nd dimension may not all be of the same length, then it's important to check that you have a square.

For example:

def ismagic(list_):
    X = len(list_) # number of rows
    for row in list_:
        if len(row) != X:
            return False # not square
    N = sum(list_[0]) # all rows, columns and diagonals must sum to this
    # check row sums
    for row in list_[1:]:
        if sum(row) != N:
            return False
    # check column sums
    for c in range(X):
        if sum(list_[r][c] for r in range(X)) != N:
            return False
    # check diagonal sums
    d1, d2 = 0, 0
    for i in range(X):
        d1 += list_[i][i]
        d2 += list_[X-i-1][X-i-1]
    return d1 == N and d2 == N

im = [[16, 2, 3, 13], [5, 11, 10, 8], [9, 7, 6, 12], [4, 14, 15, 1]]
nm = [[10, 7, 4, 5], [2, 1, 0, 8], [8, 4, 6, 1], [4, 4, 5, 1]]

print(ismagic(im))
print(ismagic(nm))

Output:

True
False
DarkKnight
  • 19,739
  • 3
  • 6
  • 22
0

Assumed that a Lo Shu Magic Square has the same sum for every columns, rows, diagonal and anti-diagonal.

def is_magic_square(square_matrix):
    # function used to check migic
    is_magic_sum = sum(square_matrix[0]).__eq__

    # check rows
    if not all(map(is_magic_sum, map(sum, square_matrix))):
        return False
    # check cols
    if not all(map(is_magic_sum, map(sum, zip(*square_matrix)))):
        return False
    # check main diagonal
    if not is_magic_sum(sum(square_matrix[i][i]) for i in range(len(square_matrix))):
        return False
    # check anti diagonal
    if not is_magic_sum(sum(square_matrix[i][len(square_matrix)-i-1] for i in range(len(square_matrix)))):
        return False

    return True
cards
  • 3,936
  • 1
  • 7
  • 25