0
votes
def magic_square(n):

    magicSquare = []

    for i in range(n):
        l=[]

        for j in range(n):
            l.append(0)

        magicSquare.append(l)



    i=n//2
    j=n-1

    num = n*n
    count = 1

    while(count<=num):
        if(i==-1 and j==n):
            j = n-2
            i = 0

        else:
            if(j==n):
                j=0

            if(i<0):
                i=n-1

        if(magicSquare[i][j]!=0):       # here iam getting error sign as(list index out of range) . how to rectify this ???
            i=i+1
            j=j-2
            continue 
        else:
            magicSquare[i][j]=count
            count+=1
    i=i-1
    j=j+1

    for i in range(n):
        for j in range(n):
            print(magicSquare[i][j],end=" ")
        print()

magic_square(3)

Result as:

runfile('D:/01The Joy Of Computing Using Python/Spyder/Magic_square.py', wdir='D:/01The Joy Of Computing Using Python/Spyder') Traceback (most recent call last):

File "", line 1, in runfile('D:/01The Joy Of Computing Using Python/Spyder/Magic_square.py', wdir='D:/01The Joy Of Computing Using Python/Spyder')

File "C:\Users\intel\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 827, in runfile execfile(filename, namespace)

File "C:\Users\intel\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile exec(compile(f.read(), filename, 'exec'), namespace)

File "D:/01The Joy Of Computing Using Python/Spyder/Magic_square.py", line 56, in magic_square(3)

File "D:/01The Joy Of Computing Using Python/Spyder/Magic_square.py", line 41, in magic_square if(magicSquare[i][j]!=0):

IndexError: list index out of range

1

1 Answers

0
votes

There were a few logic issues in your code, but I've fixed them now...

def magic_square(n):

    magicSquare = []

    for i in range(n):
        l=[]

        for j in range(n):
            l.append(0)

        magicSquare.append(l)

    i=0
    j=(n-1)//2

    num = n*n
    count = 1

    while(count<=num):
        magicSquare[i][j] = count
        count+=1

        newi = (i-1) % n
        newj = (j+1) % n

        if magicSquare[newi][newj]:
            i=(i+1) % n 
        else:
            i = newi
            j = newj


    for i in range(n):
        for j in range(n):
            print(magicSquare[i][j],end=" ")
        print()

magic_square(5)

You can also make your original list easily, using [[None for _ in range(n)] for _ in range(n)], and you can format your square using '\n'.join(' '.join(map(str, row)) for row in sq)

I've also put a function to check that the square is magic below:

def format_square(sq):
    text = '\n'.join(' '.join(map(str, row)) for row in sq)
    return text

def check_square(sq):
    n = len(sq)

    v_sum_list = set(sum(row) for row in sq)
    if len(v_sum_list) > 1:
        return False

    h_sum_list = set(sum(sq[i][x] for x in range(n)) for i in range(n))
    if len(h_sum_list) > 1:
        return False

    diagonals = set((
        sum(sq[i][i] for i in range(n)),
        sum(sq[n-i-1][n-i-1] for i in range(n))
    ))

    if not (diagonals == h_sum_list == v_sum_list):
        return False
    return True

def gen_magic_square(n):

    magic_square = [[None for _ in range(n)] for _ in range(n)]

    if n % 2 == 1:
        # odd
        x = int((n-1) / 2)
        y = 0

        total_squares = n ** 2
        filled_square_count = 1
        while filled_square_count <= total_squares:
            magic_square[y][x] = filled_square_count
            filled_square_count += 1

            newx = (x+1) % n
            newy = (y-1) % n

            if magic_square[newy][newx]:
                y += 1
                y %= n
            else:
                x = newx
                y = newy
    else:
        raise ValueError("n must be odd")

    return magic_square

sq = gen_magic_square(7)
print(check_square(sq))
print(format_square(sq))