A magic square is an NxN square matrix whose numbers consist of consecutive numbers arranged so that the sum of each row and column, and both diagonals are equal to the same sum (which is called the magic number or magic constant).

A magic square of singly even order has a size that is a multiple of 4, plus 2 (e.g. 6, 10, 14). This means that the subsquares have an odd size, which plays a role in the construction.




Task
Create a magic square of 6 x 6.




 Related tasks
 Magic squares of odd order
 Magic squares of doubly even order

 See also
 Singly Even Magic Squares (1728.org)



' version 18-03-2016
' compile with: fbc -s console
' singly even magic square 6, 10, 14, 18...
 
Sub Err_msg(msg As String)
    Print msg
    Beep : Sleep 5000, 1 : Exit Sub
End Sub
 
Sub se_magicsq(n As UInteger, filename As String = "")
 
    ' filename <> "" then save square in a file
    ' filename can contain directory name
    ' if filename exist it will be overwriten, no error checking
 
    If n < 6 Then
        Err_msg( "Error: n is to small")
        Exit Sub
    End If
 
    If ((n -2) Mod 4) <> 0 Then
        Err_msg "Error: not possible to make singly" + _
                 " even magic square size " + Str(n)
        Exit Sub
    End If
 
    Dim As UInteger sq(1 To n, 1 To n)
    Dim As UInteger magic_sum = n * (n ^ 2 +1) \ 2
    Dim As UInteger sq_d_2 = n \ 2, q2 = sq_d_2 ^ 2
    Dim As UInteger l = (n -2) \ 4
    Dim As UInteger x = sq_d_2 \ 2 + 1, y = 1, nr = 1
    Dim As String frmt = String(Len(Str(n * n)) +1, "#")
 
    ' fill pattern A C
    '              D B
    ' main loop for creating magic square in section A
    ' the value for B,C and D is derived from A
    ' uses the FreeBASIC odd order magic square routine
    Do
        If sq(x, y) = 0 Then
            sq(x         , y         ) = nr          ' A
            sq(x + sq_d_2, y + sq_d_2) = nr + q2     ' B
            sq(x + sq_d_2, y         ) = nr + q2 * 2 ' C
            sq(x         , y + sq_d_2) = nr + q2 * 3 ' D
            If nr Mod sq_d_2 = 0 Then
                y += 1
            Else
                x += 1 : y -= 1
            End If
            nr += 1
        End If
        If x > sq_d_2 Then
            x = 1
            Do While sq(x,y) <> 0
                x += 1
            Loop
        End If
        If y < 1 Then
            y = sq_d_2
            Do While sq(x,y) <> 0
                y -= 1
            Loop
        End If
    Loop Until nr > q2
 
 
    ' swap left side
    For y = 1 To sq_d_2
        For x = 1 To l
            Swap sq(x, y), sq(x,y + sq_d_2)
        Next
    Next
    ' make indent
    y = (sq_d_2 \ 2) +1
    Swap sq(1, y), sq(1, y + sq_d_2) ' was swapped, restore to orignal value
    Swap sq(l +1, y), sq(l +1, y + sq_d_2)
 
    ' swap right side
    For y = 1 To sq_d_2
        For x = n - l +2 To n
            Swap sq(x, y), sq(x,y + sq_d_2)
        Next
    Next
 
    ' check columms and rows
    For y = 1 To n
        nr = 0 : l  = 0
        For x = 1 To n
            nr += sq(x,y)
            l  += sq(y,x)
        Next
        If nr <> magic_sum Or l <> magic_sum Then
            Err_msg "Error: value <> magic_sum"
            Exit Sub
        End If
    Next
 
    ' check diagonals
    nr = 0 : l = 0
    For x = 1 To n
        nr += sq(x, x)
        l  += sq(n - x +1, n - x +1)
    Next
    If nr <> magic_sum Or l <> magic_sum Then
        Err_msg "Error: value <> magic_sum"
        Exit Sub
    End If
 
    ' printing square's on screen bigger when
    ' n > 19 results in a wrapping of the line
    Print "Single even magic square size: "; n; "*"; n
    Print "The magic sum = "; magic_sum
    Print
    For y = 1 To n
        For x = 1 To n
            Print Using frmt; sq(x, y);
        Next
        Print
    Next
 
    ' output magic square to a file with the name provided
    If filename <> "" Then
        nr = FreeFile
        Open filename For Output As #nr
        Print #nr, "Single even magic square size: "; n; "*"; n
        Print #nr, "The magic sum = "; magic_sum
        Print #nr,
        For y = 1 To n
            For x = 1 To n
                Print #nr, Using frmt; sq(x,y);
            Next
            Print #nr,
        Next
        Close #nr
    End If
 
End Sub
 
' ------=< MAIN >=------
 
se_magicsq(6, "magicse6.txt") : Print
 
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End