Problem
Write a method to return a boolean if an input grid is magic square.
A magic square is a \$NxN\$ square grid (where N is the number of cells on each side) filled with distinct positive integers in the range \${1,2,...,n^{2}}\$ such that each cell contains a different integer and the sum of the integers in each row, column and diagonal is equal. The sum is called the magic constant or magic sum of the magic square.
Code
I've tried to solve the above problem. If you'd like to review the code and provide any change/improvement recommendations please do so, and I'd really appreciate that.
from typing import List import numpy as np def is_magic_square(grid: List[List[int]]) -> bool: """Returns a boolean if an input grid is magic square""" try: grid_length = len(grid) magic_sum = float(grid_length * (grid_length ** 2 + 1) / 2) diag_positive, diag_negative = [], [] diag_count_positive = 0 diag_count_negative = grid_length - 1 col_grid = np.zeros(shape=(grid_length, grid_length)) unique_elements = set() for index_row, lists in enumerate(grid): diag_negative.append(lists[diag_count_negative]) diag_count_negative -= 1 if len(grid[index_row]) != grid_length: return False if sum(lists) != magic_sum: return False for index_col in range(grid_length): unique_elements.add(lists[index_col]) col_grid[index_col][index_row] = lists[index_col] if index_col == grid_length and index_row == grid_length - 1 and len(unique_elements) != grid_length ** 2 - 1: return False if index_row == grid_length - 1: sum_col = sum(col_grid) temp_col = np.array([magic_sum] * grid_length) if str(temp_col) != str(sum_col): return False if diag_count_positive == index_row: diag_positive.append(lists[index_row]) diag_count_positive += 1 if diag_count_positive == grid_length and sum(diag_positive) != magic_sum: return False if index_row == grid_length - 1 and sum(diag_negative) != magic_sum: return False except: return False return True if __name__ == '__main__': # ---------------------------- TEST --------------------------- DIVIDER_DASH_LINE = '-' * 50 GREEN_APPLE = '\U0001F34F' RED_APPLE = '\U0001F34E' magic_squares = [ [[4, 3, 8], [9, 5, 1], [2, 7, 6]], [[9, 3, 22, 16, 15], [2, 21, 20, 14, 8], [25, 19, 13, 7, 1], [18, 12, 6, 5, 24], [11, 10, 4, 23, 17]], [[60, 53, 44, 37, 4, 13, 20, 29], [3, 14, 19, 30, 59, 54, 43, 38], [58, 55, 42, 39, 2, 15, 18, 31], [1, 16, 17, 32, 57, 56, 41, 40], [61, 52, 45, 36, 5, 12, 21, 28], [6, 11, 22, 27, 62, 51, 46, 35], [63, 50, 47, 34, 7, 10, 23, 26], [8, 9, 24, 25, 64, 49, 48, 33]], [[35, 26, 17, 1, 62, 53, 44], [46, 37, 21, 12, 3, 64, 55], [57, 41, 32, 23, 14, 5, 66], [61, 52, 43, 34, 25, 16, 7], [2, 63, 54, 45, 36, 27, 11], [13, 4, 65, 56, 47, 31, 22], [24, 15, 6, 67, 51, 42, 33]], [[1, 35, 4, 33, 32, 6], [25, 11, 9, 28, 8, 30], [24, 14, 18, 16, 17, 22], [13, 23, 19, 21, 20, 15], [12, 26, 27, 10, 29, 7], [36, 2, 34, 3, 5, 31]], [[16, 14, 7, 30, 23], [24, 17, 10, 8, 31], [32, 25, 18, 11, 4], [5, 28, 26, 19, 12], [13, 6, 29, 22, 20]], [[1, 14, 4, 15], [8, 11, 5, 10], [13, 2, 16, 3], [12, 7, 9, 6]], [[8, 1, 6], [3, 5, 7], [4, 9, 2]] ] for magic_square in magic_squares: print(DIVIDER_DASH_LINE) if is_magic_square(magic_square) is True: print(f'{GREEN_APPLE} "{magic_square}" is a magic square.') else: print(f'{RED_APPLE} "{magic_square}" is not a magic square.')
Output
-------------------------------------------------- π "[[4, 3, 8], [9, 5, 1], [2, 7, 6]]" is a magic square. -------------------------------------------------- π "[[9, 3, 22, 16, 15], [2, 21, 20, 14, 8], [25, 19, 13, 7, 1], [18, 12, 6, 5, 24], [11, 10, 4, 23, 17]]" is a magic square. -------------------------------------------------- π "[[60, 53, 44, 37, 4, 13, 20, 29], [3, 14, 19, 30, 59, 54, 43, 38], [58, 55, 42, 39, 2, 15, 18, 31], [1, 16, 17, 32, 57, 56, 41, 40], [61, 52, 45, 36, 5, 12, 21, 28], [6, 11, 22, 27, 62, 51, 46, 35], [63, 50, 47, 34, 7, 10, 23, 26], [8, 9, 24, 25, 64, 49, 48, 33]]" is a magic square. -------------------------------------------------- π "[[35, 26, 17, 1, 62, 53, 44], [46, 37, 21, 12, 3, 64, 55], [57, 41, 32, 23, 14, 5, 66], [61, 52, 43, 34, 25, 16, 7], [2, 63, 54, 45, 36, 27, 11], [13, 4, 65, 56, 47, 31, 22], [24, 15, 6, 67, 51, 42, 33]]" is not a magic square. -------------------------------------------------- π "[[1, 35, 4, 33, 32, 6], [25, 11, 9, 28, 8, 30], [24, 14, 18, 16, 17, 22], [13, 23, 19, 21, 20, 15], [12, 26, 27, 10, 29, 7], [36, 2, 34, 3, 5, 31]]" is a magic square. -------------------------------------------------- π "[[16, 14, 7, 30, 23], [24, 17, 10, 8, 31], [32, 25, 18, 11, 4], [5, 28, 26, 19, 12], [13, 6, 29, 22, 20]]" is not a magic square. -------------------------------------------------- π "[[1, 14, 4, 15], [8, 11, 5, 10], [13, 2, 16, 3], [12, 7, 9, 6]]" is a magic square. -------------------------------------------------- π "[[8, 1, 6], [3, 5, 7], [4, 9, 2]]" is a magic square.