Jump to content

Magic squares of doubly even order

From Rosetta Code
Task
Magic squares of doubly even order
You are encouraged to solve this task according to the task description, using any language you may know.

A magic square is an   N×N  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 doubly even order has a size that is a multiple of four   (e.g.     4, 8, 12).

This means that the subsquares also have an even size, which plays a role in the construction.

1 2 62 61 60 59 7 8
9 10 54 53 52 51 15 16
48 47 19 20 21 22 42 41
40 39 27 28 29 30 34 33
32 31 35 36 37 38 26 25
24 23 43 44 45 46 18 17
49 50 14 13 12 11 55 56
57 58 6 5 4 3 63 64


Task

Create a magic square of   8 × 8.


Related tasks


See also



11l

Translation of: Java
F magicSquareDoublyEven(n)
   V bits = 1001'0110'0110'1001b
   V size = n * n
   V mult = n I/ 4

   V result = [[0] * n] * n
   V i = 0
   L(r) 0 .< n
      L(c) 0 .< n
         V bitPos = c I/ mult + (r I/ mult) * 4
         result[r][c] = I (bits [&] (1 << bitPos)) != 0 {i + 1} E size - i
         i++
   R result

V n = 8
L(row) magicSquareDoublyEven(n)
   L(x) row
      print(‘#2 ’.format(x), end' ‘’)
   print()
print("\nMagic constant: "((n * n + 1) * n I/ 2))
Output:
 1  2 62 61 60 59  7  8
 9 10 54 53 52 51 15 16
48 47 19 20 21 22 42 41
40 39 27 28 29 30 34 33
32 31 35 36 37 38 26 25
24 23 43 44 45 46 18 17
49 50 14 13 12 11 55 56
57 58  6  5  4  3 63 64

Magic constant: 260

360 Assembly

Translation of: Java
*        Magic squares of doubly even order  01/03/2017
MAGICSDB CSECT
         USING  MAGICSDB,R13
         B      72(R15)            skip save area
         DC     17F'0'             save area
         STM    R14,R12,12(R13)
         ST     R13,4(R15)
         ST     R15,8(R13)
         LR     R13,R15            end of prolog
         SR     R8,R8              k=0
         LA     R6,0               i=0
       DO WHILE=(C,R6,LE,=A(N-1))  do i=0 to n-1
         MVC    PG,=CL80' '          clear buffer
         LA     R9,PG                pgi=0
         LA     R7,0                 j=0
       DO WHILE=(C,R7,LE,=A(N-1))    do j=0 to n-1
         LR     R4,R7                  j
         SRDA   R4,32                  >>r5
         D      R4,MULT                /mult
         LR     R2,R5                  r2=j/mult
         LR     R4,R6                  i
         SRDA   R4,32                  >>r5
         D      R4,MULT                /mult
         SLA    R5,2                   r5=(i/mult)*4
         AR     R2,R5                  bitpos=j/mult+(i/mult)*4
         STC    R2,XSLL+3              number_of_shift=bitpos
         L      R5,=F'1'               1
         EX     0,XSLL                 r5=1<<bitpos  (SLL R5,bitpos)
         L      R4,BITS                bits
         NR     R4,R5                  bits and (1<<bitpos)
       IF LTR,R4,NZ,R4 THEN            if (bits and (1<<bitpos))<>0
         LA     R10,1(R8)                x=k+1
       ELSE     ,                      else
         L      R10,SIZE                 size
         SR     R10,R8                   x=size-k
       ENDIF    ,                      endif
         XDECO  R10,XDEC               edit x
         MVC    0(4,R9),XDEC+8         output x
         LA     R9,4(R9)               pgi+=4
         LA     R8,1(R8)               k++
         LA     R7,1(R7)               j++
       ENDDO    ,                    enddo j
         XPRNT  PG,L'PG              print buffer
         LA     R6,1(R6)             i++
       ENDDO    ,                  enddo i
         MVC    PG,=CL80'magic constant='
         L      R1,=A((N*N+1)*N/2) magicnum=(n*n+1)*n/2
         XDECO  R1,XDEC            edit magicnum
         MVC    PG+15(4),XDEC+8    output magicnum
         XPRNT  PG,L'PG            print buffer
         L      R13,4(0,R13)       epilog
         LM     R14,R12,12(R13)
         XR     R15,R15            rc=0
         BR     R14                exit
XSLL     SLL    R5,0               shift left logical
N        EQU    8                  <= input value n
SIZE     DC     A(N*N)             size=n*n
MULT     DC     A(N/4)             mult=n/4  (multiple of 4)
BITS     DC     XL2'0000',BL2'1001011001101001'  pattern
PG       DS     CL80               buffer
XDEC     DS     CL12               temp for xdeco
         YREGS
         END    MAGICSDB
Output:
   1   2  62  61  60  59   7   8
   9  10  54  53  52  51  15  16
  48  47  19  20  21  22  42  41
  40  39  27  28  29  30  34  33
  32  31  35  36  37  38  26  25
  24  23  43  44  45  46  18  17
  49  50  14  13  12  11  55  56
  57  58   6   5   4   3  63  64
magic constant= 260

ALGOL 60

Works with: A60
begin
	comment Magic squares of doubly even order - 10/02/2021;
    integer array pattern[1:4,1:4];
	integer n, r, c, s, m, i, b, t;
	n:=8;
	for r:=1 step 1 until 4 do
		for c:=1 step 1 until 4 do
			pattern[r,c]:=if 
				((c=1 or c=4) and (r=1 or r=4)) or
				((c=2 or c=3) and (r=2 or r=3)) then 1 else 0;
	s:=n*n;  m:=n div 4;
	outstring(1,"magic square -- n ="); outinteger(1,n); outstring(1,"\n");
	i:=0;
	for r:=1 step 1 until n do begin
		for c:=1 step 1 until n do begin
			b:=pattern[(r-1) div m+1,(c-1) div m+1];
			if b=1 then t:=i+1 else t:=s-i;
			if t less 10 then outstring(1," ");
			outinteger(1,t);
			i:=i+1
		end;
		outstring(1,"\n")
	end;
	outstring(1,"magic constant ="); outinteger(1,(s+1)*n div 2)
end
Output:
magic square -- n = 8
  1   2  62  61  60  59   7   8
  9  10  54  53  52  51  15  16
 48  47  19  20  21  22  42  41
 40  39  27  28  29  30  34  33
 32  31  35  36  37  38  26  25
 24  23  43  44  45  46  18  17
 49  50  14  13  12  11  55  56
 57  58   6   5   4   3  63  64
magic constant = 260

ALGOL 68

Translation of: ALGOL 60

Using a procedure to generate the square for easier re-use.

BEGIN # Magic squares of doubly even order #
    PROC doubly even magic square = ( INT n )[,]INT:
         IF n MOD 4 /= 0 THEN
            # not a doubly even number #
            [ 1 : 0, 1 : 0 ]INT empty square;
            empty square
         ELSE
            # ok to create the square #
            [ 1 : 4, 1 : 4 ]INT pattern;
            FOR r TO 4 DO
                FOR c TO 4 DO
                    pattern[ r, c ] := IF ( ( c = 1 OR c = 4 ) AND ( r = 1 OR r = 4 ) )
                                       OR ( ( c = 2 OR c = 3 ) AND ( r = 2 OR r = 3 ) )
                                       THEN 1
                                       ELSE 0
                                       FI
                OD
            OD;
            [ 1 : n, 1 : n ]INT result;
            INT s  = n * n, m = n OVER 4;
            INT i := 0;
            FOR r TO n DO
                FOR c TO n DO
                    result[ r, c ] := IF pattern[ ( r - 1 ) OVER m + 1, ( c - 1 ) OVER m + 1 ] = 1
                                      THEN i + 1
                                      ELSE s - i
                                      FI;
                    i +:= 1
                OD
            OD;
            result
         FI # doubly eben magic square # ;
    # test doubly even magic square #
    FOR order FROM 8 BY 4 TO 12 DO
        # calculate the field width for the elements of the square #
        INT w := 1, v := order * order;
        WHILE ( v OVERAB 10 ) > 0 DO w +:= 1 OD;
        # construct the square #
        [,]INT square = doubly even magic square( order );
        print( ( "magic square -- n = ", whole( order, 0 ), newline ) );
        FOR r FROM 1 LWB square TO 1 UPB square DO
            FOR c FROM 2 LWB square TO 2 UPB square DO
                print( ( " ", whole( square[ r, c ], - w ) ) )
            OD;
            print( ( newline ) )
        OD;
        print( ( "magic constant = ", whole( ( ( ( order * order ) + 1 ) * order ) OVER 2, 0 ), newline ) )
    OD
END
Output:
magic square -- n = 8
  1  2 62 61 60 59  7  8
  9 10 54 53 52 51 15 16
 48 47 19 20 21 22 42 41
 40 39 27 28 29 30 34 33
 32 31 35 36 37 38 26 25
 24 23 43 44 45 46 18 17
 49 50 14 13 12 11 55 56
 57 58  6  5  4  3 63 64
magic constant = 260
magic square -- n = 12
   1   2   3 141 140 139 138 137 136  10  11  12
  13  14  15 129 128 127 126 125 124  22  23  24
  25  26  27 117 116 115 114 113 112  34  35  36
 108 107 106  40  41  42  43  44  45  99  98  97
  96  95  94  52  53  54  55  56  57  87  86  85
  84  83  82  64  65  66  67  68  69  75  74  73
  72  71  70  76  77  78  79  80  81  63  62  61
  60  59  58  88  89  90  91  92  93  51  50  49
  48  47  46 100 101 102 103 104 105  39  38  37
 109 110 111  33  32  31  30  29  28 118 119 120
 121 122 123  21  20  19  18  17  16 130 131 132
 133 134 135   9   8   7   6   5   4 142 143 144
magic constant = 870

Amazing Hopper

Translation of: C++
/*
  Magic squares of doubly even order. Rosettacode.org
  By Mr. Dalien.
*/

#include <basico.h>

#proto cuadradomágico(_X_)
#synon _cuadradomágico    generarcuadradomágico

principal {
    decimales '0', fijar separador 'NULO'
    
    malla de bits(bits,'1;0;0;1','0;1;1;0','0;1;1;0','1;0;0;1')
    
    borrar pantalla
    iterar para( i=1; n=4, #(i<=3), ++i; #(n=4*i) )
        dim( #(n*n) ) matriz de ceros 'sqr'
        generar cuadrado mágico (n);
        ir a sub ( meter en tabla, sqr, #(n+1) ), para 'sqr'
        imprimir '"Magic square order ",n,\
                  "\nMagic constant : ",#((n * n + 1) * n / 2),\
                  NL,sqr,NL,NL'
        luego limpiar 'sqr'
    siguiente
    terminar
}

subrutinas

sub( meter en tabla, s, n ) {
    i=n,rareti(i, 'i')
    retener 'n', insertar columnas en 's'
                 insertar filas en 's'
    #basic{
       s[1:2:2*n-1,1:_end_]   = "---"
       s[1:_end_, 1:2:2*n-1]  = "|"
       s[1:2:_end_,1:2:_end_] = "+"
    }
    retornar 's'
}

cuadrado mágico ( n )
    iterar para ( cr=0;i=0, #(cr<n), ++cr )
         iterar para ( cc=0, #(cc<n), ++cc;++i )
             #( sqr[ (cc+n*cr)+1 ] = (bits[(cr%4+1),(cc%4+1)]) ? (i+1) : (n^2-i); )
         siguiente
    siguiente
    #( sqr = lpad(" ",3,string(sqr)))
    redim ( sqr, n, n )
retornar
Output:
Magic square order 4
Magic constant : 34
+---+---+---+---+
|  1| 15| 14|  4|
+---+---+---+---+
| 12|  6|  7|  9|
+---+---+---+---+
|  8| 10| 11|  5|
+---+---+---+---+
| 13|  3|  2| 16|
+---+---+---+---+


Magic square order 8
Magic constant : 260
+---+---+---+---+---+---+---+---+
|  1| 63| 62|  4|  5| 59| 58|  8|
+---+---+---+---+---+---+---+---+
| 56| 10| 11| 53| 52| 14| 15| 49|
+---+---+---+---+---+---+---+---+
| 48| 18| 19| 45| 44| 22| 23| 41|
+---+---+---+---+---+---+---+---+
| 25| 39| 38| 28| 29| 35| 34| 32|
+---+---+---+---+---+---+---+---+
| 33| 31| 30| 36| 37| 27| 26| 40|
+---+---+---+---+---+---+---+---+
| 24| 42| 43| 21| 20| 46| 47| 17|
+---+---+---+---+---+---+---+---+
| 16| 50| 51| 13| 12| 54| 55|  9|
+---+---+---+---+---+---+---+---+
| 57|  7|  6| 60| 61|  3|  2| 64|
+---+---+---+---+---+---+---+---+


Magic square order 12
Magic constant : 870
+---+---+---+---+---+---+---+---+---+---+---+---+
|  1|143|142|  4|  5|139|138|  8|  9|135|134| 12|
+---+---+---+---+---+---+---+---+---+---+---+---+
|132| 14| 15|129|128| 18| 19|125|124| 22| 23|121|
+---+---+---+---+---+---+---+---+---+---+---+---+
|120| 26| 27|117|116| 30| 31|113|112| 34| 35|109|
+---+---+---+---+---+---+---+---+---+---+---+---+
| 37|107|106| 40| 41|103|102| 44| 45| 99| 98| 48|
+---+---+---+---+---+---+---+---+---+---+---+---+
| 49| 95| 94| 52| 53| 91| 90| 56| 57| 87| 86| 60|
+---+---+---+---+---+---+---+---+---+---+---+---+
| 84| 62| 63| 81| 80| 66| 67| 77| 76| 70| 71| 73|
+---+---+---+---+---+---+---+---+---+---+---+---+
| 72| 74| 75| 69| 68| 78| 79| 65| 64| 82| 83| 61|
+---+---+---+---+---+---+---+---+---+---+---+---+
| 85| 59| 58| 88| 89| 55| 54| 92| 93| 51| 50| 96|
+---+---+---+---+---+---+---+---+---+---+---+---+
| 97| 47| 46|100|101| 43| 42|104|105| 39| 38|108|
+---+---+---+---+---+---+---+---+---+---+---+---+
| 36|110|111| 33| 32|114|115| 29| 28|118|119| 25|
+---+---+---+---+---+---+---+---+---+---+---+---+
| 24|122|123| 21| 20|126|127| 17| 16|130|131| 13|
+---+---+---+---+---+---+---+---+---+---+---+---+
|133| 11| 10|136|137|  7|  6|140|141|  3|  2|144|
+---+---+---+---+---+---+---+---+---+---+---+---+

AppleScript

Translation of: JavaScript
-- MAGIC SQUARE OF DOUBLY EVEN ORDER -----------------------------------------

-- magicSquare :: Int -> [[Int]]
on magicSquare(n)
    if n mod 4 > 0 then
        {}
    else
        set sqr to n * n
        
        set maybePowerOfTwo to asPowerOfTwo(sqr)
        if maybePowerOfTwo is not missing value then
            
            -- For powers of 2, the (append not) 'magic' series directly
            -- yields the truth table that we need
            set truthSeries to magicSeries(maybePowerOfTwo)
        else
            -- where n is not a power of 2, we can replicate a
            -- minimum truth table, horizontally and vertically
            
            script scale
                on |λ|(x)
                    replicate(n / 4, x)
                end |λ|
            end script
            
            set truthSeries to ¬
                flatten(scale's |λ|(map(scale, splitEvery(4, magicSeries(4)))))
        end if
        
        set limit to sqr + 1
        script inOrderOrReversed
            on |λ|(x, i)
                cond(x, i, limit - i)
            end |λ|
        end script
        
        -- Taken directly from an integer series  [1..sqr] where True
        -- and from the reverse of that series where False
        splitEvery(n, map(inOrderOrReversed, truthSeries))
    end if
end magicSquare

-- magicSeries :: Int -> [Bool]
on magicSeries(n)
    script boolToggle
        on |λ|(x)
            not x
        end |λ|
    end script
    
    if n  0 then
        {true}
    else
        set xs to magicSeries(n - 1)
        xs & map(boolToggle, xs)
    end if
end magicSeries


-- TEST ----------------------------------------------------------------------
on run
    
    formattedTable(magicSquare(8))
    
end run

-- formattedTable :: [[Int]] -> String
on formattedTable(lstTable)
    set n to length of lstTable
    set w to 2.5 * n
    "magic(" & n & ")" & linefeed & wikiTable(lstTable, ¬
        false, "text-align:center;width:" & ¬
        w & "em;height:" & w & "em;table-layout:fixed;")
end formattedTable

-- wikiTable :: [Text] -> Bool -> Text -> Text
on wikiTable(lstRows, blnHdr, strStyle)
    script fWikiRows
        on |λ|(lstRow, iRow)
            set strDelim to cond(blnHdr and (iRow = 0), "!", "|")
            set strDbl to strDelim & strDelim
            linefeed & "|-" & linefeed & strDelim & space & ¬
                intercalate(space & strDbl & space, lstRow)
        end |λ|
    end script
    
    linefeed & "{| class=\"wikitable\" " & ¬
        cond(strStyle  "", "style=\"" & strStyle & "\"", "") & ¬
        intercalate("", ¬
            map(fWikiRows, lstRows)) & linefeed & "|}" & linefeed
end wikiTable


-- GENERIC FUNCTIONS ---------------------------------------------------------

-- asPowerOfTwo :: Int -> maybe Int
on asPowerOfTwo(n)
    if not isPowerOf(2, n) then
        missing value
    else
        set strCMD to ("echo 'l(" & n as string) & ")/l(2)' | bc -l"
        (do shell script strCMD) as integer
    end if
end asPowerOfTwo

-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
    script append
        on |λ|(a, b)
            a & b
        end |λ|
    end script
    
    foldl(append, {}, map(f, xs))
end concatMap

-- cond :: Bool -> a -> a -> a
on cond(bool, f, g)
    if bool then
        f
    else
        g
    end if
end cond

-- flatten :: Tree a -> [a]
on flatten(t)
    if class of t is list then
        concatMap(my flatten, t)
    else
        t
    end if
end flatten

-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
    tell mReturn(f)
        set v to startValue
        set lng to length of xs
        repeat with i from 1 to lng
            set v to |λ|(v, item i of xs, i, xs)
        end repeat
        return v
    end tell
end foldl

-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
    set {dlm, my text item delimiters} to {my text item delimiters, strText}
    set strJoined to lstText as text
    set my text item delimiters to dlm
    return strJoined
end intercalate

-- isPowerOf :: Int -> Int -> Bool
on isPowerOf(k, n)
    set v to k
    script remLeft
        on |λ|(x)
            x mod v is not 0
        end |λ|
    end script
    
    script integerDiv
        on |λ|(x)
            x div v
        end |λ|
    end script
    
    |until|(remLeft, integerDiv, n) = 1
end isPowerOf

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map


-- Lift 2nd class handler function into 1st class script wrapper 
-- mReturn :: Handler -> Script
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn

-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary 
-- assembly of a target length

-- replicate :: Int -> a -> [a]
on replicate(n, a)
    set out to {}
    if n < 1 then return out
    set dbl to {a}
    
    repeat while (n > 1)
        if (n mod 2) > 0 then set out to out & dbl
        set n to (n div 2)
        set dbl to (dbl & dbl)
    end repeat
    return out & dbl
end replicate

-- splitAt :: Int -> [a] -> ([a],[a])
on splitAt(n, xs)
    if n > 0 and n < length of xs then
        if class of xs is text then
            {items 1 thru n of xs as text, items (n + 1) thru -1 of xs as text}
        else
            {items 1 thru n of xs, items (n + 1) thru -1 of xs}
        end if
    else
        if n < 1 then
            {{}, xs}
        else
            {xs, {}}
        end if
    end if
end splitAt

-- splitEvery :: Int -> [a] -> [[a]]
on splitEvery(n, xs)
    if length of xs  n then
        {xs}
    else
        set {gp, t} to splitAt(n, xs)
        {gp} & splitEvery(n, t)
    end if
end splitEvery

-- until :: (a -> Bool) -> (a -> a) -> a -> a
on |until|(p, f, x)
    set mp to mReturn(p)
    set v to x
    
    tell mReturn(f)
        repeat until mp's |λ|(v)
            set v to |λ|(v)
        end repeat
    end tell
    return v
end |until|
Output:

magic(8)

1 63 62 4 60 6 7 57
56 10 11 53 13 51 50 16
48 18 19 45 21 43 42 24
25 39 38 28 36 30 31 33
32 34 35 29 37 27 26 40
41 23 22 44 20 46 47 17
49 15 14 52 12 54 55 9
8 58 59 5 61 3 2 64

AWK

Translation of: C#

Since standard awk does not support bitwise operators, we provide the function countup to do the magic.

# Usage: GAWK -f MAGIC_SQUARES_OF_DOUBLY_EVEN_ORDER.AWK
BEGIN {
    n = 8
    msquare[0, 0] = 0
    if (magicsquaredoublyeven(msquare, n)) {
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                printf("%2d ", msquare[i, j])
            }
            printf("\n")
        }
        printf("\nMagic constant: %d\n", (n * n + 1) * n / 2)
        exit 1
    } else {
        exit 0
    }
}
function magicsquaredoublyeven(msquare, n,    size, mult, r, c, i) {
    if (n < 4 || n % 4 != 0) {
        printf("Base must be a positive multiple of 4.\n")
        return 0
    }
    size = n * n
    mult = n / 4 # how many multiples of 4

    i = 0
    for (r = 0; r < n; r++) {
        for (c = 0; c < n; c++) {
            msquare[r, c] = countup(r, c, mult) ? i + 1 : size - i
            i++
        }
    }
    return 1
}
function countup(r, c, mult,    pattern, bitpos) {
    # Returns 1, if we are in a count-up zone (0 otherwise)
    pattern = "1001011001101001"
    bitpos =  int(c / mult) + int(r / mult) * 4 + 1
    return substr(pattern, bitpos, 1) + 0
}
Output:
 1  2 62 61 60 59  7  8
 9 10 54 53 52 51 15 16
48 47 19 20 21 22 42 41
40 39 27 28 29 30 34 33
32 31 35 36 37 38 26 25
24 23 43 44 45 46 18 17
49 50 14 13 12 11 55 56
57 58  6  5  4  3 63 64

Magic constant: 260

Befunge

The size, N, is specified by the first value on the stack. The algorithm is loosely based on the Java implementation.

8>>>v>10p00g:*1-*\110g2*-*+1+.:00g%!9+,:#v_@
p00:<^:!!-!%3//4g00%g00\!!%3/*:g00*4:::-1<*:
Output:
1       2       62      61      60      59      7       8
9       10      54      53      52      51      15      16
48      47      19      20      21      22      42      41
40      39      27      28      29      30      34      33
32      31      35      36      37      38      26      25
24      23      43      44      45      46      18      17
49      50      14      13      12      11      55      56
57      58      6       5       4       3       63      64

C

Takes number of rows from command line, prints out usage on incorrect invocation.

#include<stdlib.h>
#include<ctype.h>
#include<stdio.h>

int** doublyEvenMagicSquare(int n) {
	if (n < 4 || n % 4 != 0)
		return NULL;

	int bits = 38505;
	int size = n * n;
	int mult = n / 4,i,r,c,bitPos;

	int** result = (int**)malloc(n*sizeof(int*));
	
	for(i=0;i<n;i++)
		result[i] = (int*)malloc(n*sizeof(int));

	for (r = 0, i = 0; r < n; r++) {
		for (c = 0; c < n; c++, i++) {
			bitPos = c / mult + (r / mult) * 4;
			result[r][c] = (bits & (1 << bitPos)) != 0 ? i + 1 : size - i;
		}
	}
	return result;
}

int numDigits(int n){
	int count = 1;
	
	while(n>=10){
		n /= 10;
		count++;
	}
	
	return count;
}

void printMagicSquare(int** square,int rows){
	int i,j,baseWidth = numDigits(rows*rows) + 3;
	
	printf("Doubly Magic Square of Order : %d and Magic Constant : %d\n\n",rows,(rows * rows + 1) * rows / 2);
	
	for(i=0;i<rows;i++){
		for(j=0;j<rows;j++){
			printf("%*s%d",baseWidth - numDigits(square[i][j]),"",square[i][j]);
		}
		printf("\n");
	}
}

int main(int argC,char* argV[])
{
	int n;
	
	if(argC!=2||isdigit(argV[1][0])==0)
		printf("Usage : %s <integer specifying rows in magic square>",argV[0]);
	else{
		n = atoi(argV[1]);
		printMagicSquare(doublyEvenMagicSquare(n),n);
	}
	return 0;
}

Invocation and Output :

C:\rosettaCode>doublyEvenMagicSquare 12
Doubly Magic Square of Order : 12 and Magic Constant : 870

     1     2     3   141   140   139   138   137   136    10    11    12
    13    14    15   129   128   127   126   125   124    22    23    24
    25    26    27   117   116   115   114   113   112    34    35    36
   108   107   106    40    41    42    43    44    45    99    98    97
    96    95    94    52    53    54    55    56    57    87    86    85
    84    83    82    64    65    66    67    68    69    75    74    73
    72    71    70    76    77    78    79    80    81    63    62    61
    60    59    58    88    89    90    91    92    93    51    50    49
    48    47    46   100   101   102   103   104   105    39    38    37
   109   110   111    33    32    31    30    29    28   118   119   120
   121   122   123    21    20    19    18    17    16   130   131   132
   133   134   135     9     8     7     6     5     4   142   143   144

C#

Translation of: Java
using System;

namespace MagicSquareDoublyEven
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 8;
            var result = MagicSquareDoublyEven(n);
            for (int i = 0; i < result.GetLength(0); i++)
            {
                for (int j = 0; j < result.GetLength(1); j++)
                    Console.Write("{0,2} ", result[i, j]);
                Console.WriteLine();
            }
            Console.WriteLine("\nMagic constant: {0} ", (n * n + 1) * n / 2);
            Console.ReadLine();
        }

        private static int[,] MagicSquareDoublyEven(int n)
        {
            if (n < 4 || n % 4 != 0)
                throw new ArgumentException("base must be a positive "
                        + "multiple of 4");

            // pattern of count-up vs count-down zones
            int bits = 0b1001_0110_0110_1001;
            int size = n * n;
            int mult = n / 4;  // how many multiples of 4

            int[,] result = new int[n, n];

            for (int r = 0, i = 0; r < n; r++)
            {
                for (int c = 0; c < n; c++, i++)
                {
                    int bitPos = c / mult + (r / mult) * 4;
                    result[r, c] = (bits & (1 << bitPos)) != 0 ? i + 1 : size - i;
                }
            }
            return result;
        }
    }
}
 1  2 62 61 60 59  7  8
 9 10 54 53 52 51 15 16
48 47 19 20 21 22 42 41
40 39 27 28 29 30 34 33
32 31 35 36 37 38 26 25
24 23 43 44 45 46 18 17
49 50 14 13 12 11 55 56
57 58  6  5  4  3 63 64

Magic constant: 260

C++

#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;

class magicSqr
{
public: 
    magicSqr( int d ) {
        while( d % 4 > 0 ) { d++; }
        sz = d;
        sqr = new int[sz * sz];
        fillSqr();
    }
    ~magicSqr() { delete [] sqr; }

    void display() const {
        cout << "Doubly Even Magic Square: " << sz << " x " << sz << "\n";
        cout << "It's Magic Sum is: " << magicNumber() << "\n\n";
        ostringstream cvr; cvr << sz * sz;
        int l = cvr.str().size();
 
        for( int y = 0; y < sz; y++ ) {
            int yy = y * sz;
            for( int x = 0; x < sz; x++ ) {
                cout << setw( l + 2 ) << sqr[yy + x];
            }
            cout << "\n";
        }
        cout << "\n\n";
    }
private:
    void fillSqr() {
        static const bool tempAll[4][4] = {{ 1, 0, 0, 1 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 1, 0, 0, 1 } };
        int i = 0;
        for( int curRow = 0; curRow < sz; curRow++ ) {
            for( int curCol = 0; curCol < sz; curCol++ ) {
                sqr[curCol + sz * curRow] = tempAll[curRow % 4][curCol % 4] ? i + 1 : sz * sz - i;
                i++;
            }
        }
    }
    int magicNumber() const { return sz * ( ( sz * sz ) + 1 ) / 2; }
 
    int* sqr;
    int sz;
};
 
int main( int argc, char* argv[] ) {
    magicSqr s( 8 );
    s.display();
    return 0;
}
Output:
Doubly Even Magic Square: 8 x 8
It's Magic Sum is: 260

   1  63  62   4   5  59  58   8
  56  10  11  53  52  14  15  49
  48  18  19  45  44  22  23  41
  25  39  38  28  29  35  34  32
  33  31  30  36  37  27  26  40
  24  42  43  21  20  46  47  17
  16  50  51  13  12  54  55   9
  57   7   6  60  61   3   2  64

D

Translation of: Java
import std.stdio;

void main() {
    int n=8;
    foreach(row; magicSquareDoublyEven(n)) {
        foreach(col; row) {
            writef("%2s ", col);
        }
        writeln;
    }
    writeln("\nMagic constant: ", (n*n+1)*n/2);
}

int[][] magicSquareDoublyEven(int n) {
    import std.exception;
    enforce(n>=4 && n%4 == 0, "Base must be a positive multiple of 4");

    int bits = 0b1001_0110_0110_1001;
    int size = n * n;
    int mult = n / 4;  // how many multiples of 4

    int[][] result;
    result.length = n;
    foreach(i; 0..n) {
        result[i].length = n;
    }

    for (int r=0, i=0; r<n; r++) {
        for (int c=0; c<n; c++, i++) {
            int bitPos = c / mult + (r / mult) * 4;
            result[r][c] = (bits & (1 << bitPos)) != 0 ? i + 1 : size - i;
        }
    }

    return result;
}
Output:
 1  2 62 61 60 59  7  8
 9 10 54 53 52 51 15 16
48 47 19 20 21 22 42 41
40 39 27 28 29 30 34 33
32 31 35 36 37 38 26 25
24 23 43 44 45 46 18 17
49 50 14 13 12 11 55 56
57 58  6  5  4  3 63 64

Magic constant: 260

EasyLang

Translation of: Lua
func[][] mkarr s .
   len q[][] s
   for i = 1 to s
      len q[i][] s
   .
   return q[][]
.
func[][] mk_oms s .
   q[][] = mkarr s
   r = 1
   c = 1 + s div 2
   for p = 1 to s * s
      q[r][c] = p
      tc = c + 1
      if tc > s
         tc = 1
      .
      tr = r - 1
      if tr < 1
         tr = s
      .
      if q[tr][tc] <> 0
         tc = c
         tr = r + 1
      .
      c = tc
      r = tr
   .
   return q[][]
.
func[][] mk_dems s .
   q[][] = mkarr s
   tmp[][] = [ [ 1 0 0 1 ] [ 0 1 1 0 ] [ 0 1 1 0 ] [ 1 0 0 1 ] ]
   tot = s * s
   for r = 1 to s
      for c = 1 to s
         sx = c mod 4
         if sx < 1
            sx = 4
         .
         sy = r mod 4
         if sy < 1
            sy = 4
         .
         if tmp[sy][sx] = 1
            q[r][c] = n + 1
         else
            q[r][c] = tot - n
         .
         n += 1
      .
   .
   return q[][]
.
numfmt 0 2
print mk_dems 8
Output:
[
 [  1 63 62  4  5 59 58  8 ]
 [ 56 10 11 53 52 14 15 49 ]
 [ 48 18 19 45 44 22 23 41 ]
 [ 25 39 38 28 29 35 34 32 ]
 [ 33 31 30 36 37 27 26 40 ]
 [ 24 42 43 21 20 46 47 17 ]
 [ 16 50 51 13 12 54 55  9 ]
 [ 57  7  6 60 61  3  2 64 ]
]

EDSAC order code

[Magic squares of doubly even order, for Rosetta Code.
 EDSAC program, Initial Orders 2.]
[====================================================================================
Certain cells in the square are marked, such that if a cell is marked then so is
its reflection in the centre point of the square. Cells are numbered 1, 2, 3 ...
from left to right and top to bottom, but if a cell is marked it is swapped with its
reflection. Two marking methods are used, illustrated below for an 8x8 square.
  + o o + + o o +        + + o o o o + +
  o + + o o + + o        + + o o o o + +
  o + + o o + + o        o o + + + + o o
  + o o + + o o +        o o + + + + o o        o = unmarked
  + o o + + o o +        o o + + + + o o        + = marked
  o + + o o + + o        o o + + + + o o
  o + + o o + + o        + + o o o o + +
  + o o + + o o +        + + o o o o + +
  Diagonal method        Rectangle method
====================================================================================]
      [Arrange the storage]
          T45K P56F       [H parameter: subroutine to print string]
          T46K P100F      [N parameter: subroutine to print number]
          T47K P204F      [M parameter: main routine]
          T54K P200F      [C parameter: constants read by subroutine R2]

[Library subroutine R2: reads integers from tape and can then be overwritten.]
          GK T20F VD L8F A40D UD TF I40F A40F S39F G@ S2F G23F A5@ T5@ E4@ E13Z
          T#C             [tell R2 where to store values]
    13743895347F8589934592#TZ
[C parameter: masks read in by subroutine R2, not by the regular loader]
    [0]   PF PF           [diagonal method,  binary 01100110011001100110011001100110011]
    [2]   PF PF           [rectangle method, binary 01000000000000000000000000000000000]

[M parameter Main routine + high-level subroutine]
          E25K TM GK 
[35-bit values, must be at even address]
    [0]   PF PF           [initial value of x mask]
    [2]   PF              [x-mask, low 17 bits]
    [3]   PF              [x-mask, high 17 bits]
    [4]   PF              [y-mask, low 17 bits]
    [5]   PF              [y-mask, high 17 bits]
[17-bit values]
    [6]   PF              [sign bit from y mask]
    [7]   PF              [m, input by user]
    [8]   PF              [n = 4*m = order of magic square]
    [9]   PF              [n^2 + 1]
   [10]   PF              [negative counter for x-values (columns)]
   [11]   PF              [negative counter for y-values (rows)]
   [12]   PF              [current entry 1, 2, 3, ...]
   [13]   PD              [constant 1]
   [14]   K4096F          [null]
   [15]   !F              [space]
   [16]   @F              [carriage return]
   [17]   &F              [line feed]
   [18]   P10F            [to check for user dialling '0']
[Strings to be printed]
   [19]   K2048FMFAFGFIFCF!FSFQFUFAFRFEF!FOFFF!FOFRFDFEFRF!F#FRF*FMF@F&FK4096F
   [49]   K2048FDFIFAFLF!FMF!F#FKFPF!F*FTFOF!FCFAFNFCFEFLF#FLF!FK4096F
   [75]   K2048FDFIFAFGFOFNFAFLF!FMFEFTFHFOFDF#FCF@F&FK4096F
   [96]   K2048FRFEFCFTFAFNFGFLFEF!FMFEFTFHFOFDF#FCF@F&FK4096F

[Enter with acc = 0]
  [118]   A118@ GH A19@   [print 'MAGIC SQUARE OF ORDER 4M']
  [121]   A121@ GH A49@   [print 'DIAL M (0 TO CANCEL)']
          ZF              [halt machine; restarts when user dials a number]
        [Here acc holds number of pulses in address field]
          S18@ E175@      [exit if dialled '0' (10 pulses)]
          A18@            [restore acc after test; m is in address field]
          L512F           [shift 11 left for printing]
          UF              [temp to 0F]
          OF O16@ O17@    [print m followed by CR, LF]
          R1024F          [shift 12 right, m is now right-justified]
          U7@             [store m]
          L1F T8@         [shift 2 left and store n = 4*m]
          H8@ V8@         [acc := n^2]
          L64F L64F       [shift 16 left to adjust scaling after mult]
          A13@ T9@        [store n^2 + 1 = sum of a cell and its reflection]
  [143]   A143@ GH A75@   [print 'DIAGONAL METHOD:']
          A#C             [acc := diagonal mask]
          U#@             [store as x-mask at start of each row]
          T4#@            [also as initial value of y-mask]
  [149]   A149@ G177@     [call subroutine to print magic square]
  [151]   A151@ GH A96@   [print 'RECTANGLE METHOD:']
          A2#C U4D T6D    [copy rectangke mask to 4D and 6D]
          S7@             [initialize negative counter to -m]
  [158]   TF              [loop: update negative counter in 0F]
          A4D RD T4D      [shift 4D 1 right]
          A6D R2F T6D     [shift 6D 3 right]
          AF A13@         [inc negative counter]
          G158@           [loop back till done m times]
          A4D S6D L1F     [acc := 4D - 6D, then 2 left]
        [Mask in binary is now 0 (m times) 1 (2*m times) 0...0]
          U#@             [store as x-mask at start of each row]
          T4#@            [also as initial value of y-mask]
  [173]   A173@ G177@     [call subroutine to print magic square]
  [175]   O14@            [done; print null to flush teleprinter buffer]
          ZF              [halt machine]

[Subroutine to print magic square after x- and y-mask have been initialized.]
[It's assumed that strings printed by caller leave teleprinter in figures mode.]
  [177]   A3F T220@       [plant return link as usual]
          A15@ T1F        [space replaces leading 0 when printing]
          T12@            [initialize cell entry to 0]
          S8@             [initialize negative counter of rows to -n]
[Start of row]
  [183]   T11@            [update negative counter of rows]
          A#@ T2#@        [reset x-mask for start of row]
          H14@ C5@ T6@    [isolate sign bit of y-mask]
          S8@             [initialize negative counter of columns to -n]
[Next cell in this row.
 Cell is considered marked if sign bits in x- and y-masks are equal.
 Or could say marked if sign bits are unequal; would also give a magic square.]
  [190]   T10@            [update negative counter of columns]
          A12@ A13@ T12@  [inc cell entry]
          A3@ A6@         [compare signs in x- and y-masks]
          E200@           [jump if equal (or could replace E by G)]
          TF              [clear acc]
          A12@            [acc := entry]
          E203@           [join common code]
  [200]   TF              [clear acc]
          A9@ S12@        [acc := complement of entry]
  [203]   TF              [to 0F for printing]
  [204]   A204@ GN        [print number]
          A2#@ LD T2#@    [shift x-mask 1 left]
          A10@ A13@       [inc negative counter of cells]
          G190@           [loop till row is complete]
[End of row]
          O16@ O17@       [print CR, LF]
          A4#@ LD T4#@    [shift y-mask 1 left]
          A11@ A13@       [inc negative counter of rows]
          G183@           [loop till magic square is complete]
  [220]   ZF              [(planted) jump back to caller]

[H parameter: Subroutine to print a string.]
          E25K TH
[Input: A order for first character must follow subroutine call (G order)
 String is terminated with EDSAC null, which is sent to the teleprinter.]
    GKA18@U17@S19@T4@AFT6@AFUFOFE12@A20@G16@TFA6@A2FG5@TFZFU3FU1FK2048F

[N parameter: Subroutine to print non-negative 17-bit integer.]
          E25K TN
[Parameters: 0F = integer to be printed (not preserved)
             1F = character for leading zero (preserved)
 Workspace: 4F..7F, 38 locations]
    GKA3FT34@A1FT7FS35@T6FT4#FAFT4FH36@V4FRDA4#FR1024FH37@E23@O7FA2F
    T6FT5FV4#FYFL8FT4#FA5FL1024FUFA6FG16@OFTFT7FA6FG17@ZFP4FZ219DTF

[M parameter again]
          E25K TM GK
          E118Z           [define entry point]
          PF              [acc = 0 on entry]
Output:
MAGIC SQUARE OF ORDER 4M
DIAL M (0 TO CANCEL) 2
DIAGONAL METHOD:
   64    2    3   61   60    6    7   57
    9   55   54   12   13   51   50   16
   17   47   46   20   21   43   42   24
   40   26   27   37   36   30   31   33
   32   34   35   29   28   38   39   25
   41   23   22   44   45   19   18   48
   49   15   14   52   53   11   10   56
    8   58   59    5    4   62   63    1
RECTANGLE METHOD:
   64   63    3    4    5    6   58   57
   56   55   11   12   13   14   50   49
   17   18   46   45   44   43   23   24
   25   26   38   37   36   35   31   32
   33   34   30   29   28   27   39   40
   41   42   22   21   20   19   47   48
   16   15   51   52   53   54   10    9
    8    7   59   60   61   62    2    1

Elena

Translation of: C#

ELENA 6.x :

import system'routines;
import extensions;
import extensions'routines;
 
MagicSquareDoublyEven(int n)
{
    if(n < 4 || n.mod(4) != 0)
        { InvalidArgumentException.new("base must be a positive multiple of 4").raise() };
 
    int bits := 09669h;
    int size := n * n;
    int mult := n / 4;
 
    var result := IntMatrix.allocate(n,n);
    int i := 0;
    for (int r := 0; r < n; r += 1)
    {
        for(int c := 0; c < n; c += 1; i += 1)
        {
            int bitPos := c / mult + (r / mult) * 4;
 
            result[r][c] := ((bits & (1 $shl bitPos)) != 0).iif(i+1,size - i)
        }
    };
 
    ^ result
}
 
public program()
{
    int n := 8;
 
    console.printLine(MagicSquareDoublyEven(n));
 
    console.printLine().printLine("Magic constant: ",(n * n + 1) * n / 2)
}
Output:
1,2,62,61,60,59,7,8
9,10,54,53,52,51,15,16
48,47,19,20,21,22,42,41
40,39,27,28,29,30,34,33
32,31,35,36,37,38,26,25
24,23,43,44,45,46,18,17
49,50,14,13,12,11,55,56
57,58,6,5,4,3,63,64

Magic constant: 260

Elixir

defmodule Magic_square do
  def doubly_even(n) when rem(n,4)!=0, do: raise ArgumentError, "must be even, but not divisible by 4."
  def doubly_even(n) do
    n2 = n * n
    Enum.zip(1..n2, make_pattern(n))
    |> Enum.map(fn {i,p} -> if p, do: i, else: n2 - i + 1 end)
    |> Enum.chunk(n)
    |> to_string(n)
    |> IO.puts
  end
  
  defp make_pattern(n) do
    pattern = Enum.reduce(1..4, [true], fn _,acc ->
                acc ++ Enum.map(acc, &(!&1))
              end) |> Enum.chunk(4)
    for i <- 0..n-1, j <- 0..n-1, do: Enum.at(pattern, rem(i,4)) |> Enum.at(rem(j,4))
  end
 
  defp to_string(square, n) do
    format = String.duplicate("~#{length(to_char_list(n*n))}w ", n) <> "\n"
    Enum.map_join(square, fn row ->
      :io_lib.format(format, row)
    end)
  end
end

Magic_square.doubly_even(8)
Output:
 1 63 62  4  5 59 58  8
56 10 11 53 52 14 15 49
48 18 19 45 44 22 23 41
25 39 38 28 29 35 34 32
33 31 30 36 37 27 26 40
24 42 43 21 20 46 47 17
16 50 51 13 12 54 55  9
57  7  6 60 61  3  2 64

Factor

USING: arrays combinators.short-circuit formatting fry
generalizations kernel math math.matrices prettyprint sequences
;
IN: rosetta-code.doubly-even-magic-squares

: top?    ( loc n -- ? ) [ second ] dip 1/4 * <  ;
: bottom? ( loc n -- ? ) [ second ] dip 3/4 * >= ;
: left?   ( loc n -- ? ) [ first  ] dip 1/4 * <  ;
: right?  ( loc n -- ? ) [ first  ] dip 3/4 * >= ;
: corner? ( loc n -- ? )
    {
        [ { [ top?    ] [ left?  ] } ]
        [ { [ top?    ] [ right? ] } ]
        [ { [ bottom? ] [ left?  ] } ]
        [ { [ bottom? ] [ right? ] } ]
    } [ 2&& ] map-compose 2|| ;

: center? ( loc n -- ? )
    { [ top? ] [ bottom? ] [ left? ] [ right? ] } [ not ]
    map-compose 2&& ;

: backward? ( loc n -- ? ) { [ corner? ] [ center? ] } 2|| ;
: forward   ( loc n -- m ) [ first2 ] dip * 1 + + ;
: backward  ( loc n -- m ) tuck forward [ sq ] dip - 1 + ;

: (doubly-even-magic-square) ( n -- matrix )
    [ dup 2array matrix-coordinates flip ] [ 3 dupn ] bi
    '[ dup _ backward? [ _ backward ] [ _ forward ] if ]
    matrix-map ;

ERROR: invalid-order order ;

: check-order ( n -- )
    dup { [ zero? not ] [ 4 mod zero? ] } 1&& [ drop ]
    [ invalid-order ] if ;

: doubly-even-magic-square ( n -- matrix )
    dup check-order (doubly-even-magic-square) ;

: main ( -- )
    { 4 8 12 } [
        dup doubly-even-magic-square dup
        [ "Order: %d\n" printf ]
        [ simple-table. ]
        [ first sum "Magic constant: %d\n\n" printf ] tri*
    ] each ;

MAIN: main
Output:
Order: 4
16 2  3  13
5  11 10 8
9  7  6  12
4  14 15 1
Magic constant: 34

Order: 8
64 63 3  4  5  6  58 57
56 55 11 12 13 14 50 49
17 18 46 45 44 43 23 24
25 26 38 37 36 35 31 32
33 34 30 29 28 27 39 40
41 42 22 21 20 19 47 48
16 15 51 52 53 54 10 9
8  7  59 60 61 62 2  1
Magic constant: 260

Order: 12
144 143 142 4   5   6   7   8   9   135 134 133
132 131 130 16  17  18  19  20  21  123 122 121
120 119 118 28  29  30  31  32  33  111 110 109
37  38  39  105 104 103 102 101 100 46  47  48
49  50  51  93  92  91  90  89  88  58  59  60
61  62  63  81  80  79  78  77  76  70  71  72
73  74  75  69  68  67  66  65  64  82  83  84
85  86  87  57  56  55  54  53  52  94  95  96
97  98  99  45  44  43  42  41  40  106 107 108
36  35  34  112 113 114 115 116 117 27  26  25
24  23  22  124 125 126 127 128 129 15  14  13
12  11  10  136 137 138 139 140 141 3   2   1
Magic constant: 870

FreeBASIC

' version 18-03-2016
' compile with: fbc -s console
' doubly even magic square 4, 8, 12, 16...

Sub Err_msg(msg As String)
    Print msg
    Beep : Sleep 5000, 1 : Exit Sub
End Sub

Sub de_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 < 4 Then
        Err_msg( "Error: n is to small")
        Exit Sub
    End If

    If (n Mod 4) <> 0 Then
        Err_msg "Error: not possible to make doubly" + _
        " 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 q = n \ 4
    Dim As UInteger x, y, nr = 1
    Dim As String frmt = String(Len(Str(n * n)) +1, "#")

    ' set up the square
    For y = 1 To n
        For x = q +1 To n - q
            sq(x,y) = 1
        Next
    Next
    For x = 1 To n
        For y = q +1 To n - q
            sq(x, y) Xor= 1
        Next
    Next

    ' fill the square
    q = n * n +1
    For y = 1 To n
        For x = 1 To n
            If sq(x,y) = 0 Then
                sq(x,y) = q - nr
            Else
                sq(x,y) = nr
            End If
            nr += 1
        Next
    Next

    ' check columms and rows
    For y = 1 To n
        nr = 0 : q = 0
        For x = 1 To n
            nr += sq(x,y)
            q += sq(y,x)
        Next
        If nr <> magic_sum Or q <> magic_sum Then
            Err_msg "Error: value <> magic_sum"
            Exit Sub
        End If
    Next

    ' check diagonals
    nr = 0 : q = 0
    For x = 1 To n
        nr += sq(x, x)
        q += sq(n - x +1, n - x +1)
    Next
    If nr <> magic_sum Or q <> 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 >=------

de_magicsq(8, "magic8de.txt") : Print

' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End
Output:
Single even magic square size: 8*8
The magic sum = 260

 64 63  3  4  5  6 58 57
 56 55 11 12 13 14 50 49
 17 18 46 45 44 43 23 24
 25 26 38 37 36 35 31 32
 33 34 30 29 28 27 39 40
 41 42 22 21 20 19 47 48
 16 15 51 52 53 54 10  9
  8  7 59 60 61 62  2  1

Go

package main

import (
	"fmt"
	"log"
	"strings"
)

const dimensions int = 8

func setupMagicSquareData(d int) ([][]int, error) {
	var output [][]int
	if d < 4 || d%4 != 0 {
		return [][]int{}, fmt.Errorf("Square dimension must be a positive number which is divisible by 4")
	}
	var bits uint = 0x9669 // 0b1001011001101001
	size := d * d
	mult := d / 4
	for i, r := 0, 0; r < d; r++ {
		output = append(output, []int{})
		for c := 0; c < d; i, c = i+1, c+1 {
			bitPos := c/mult + (r/mult)*4
			if (bits & (1 << uint(bitPos))) != 0 {
				output[r] = append(output[r], i+1)
			} else {
				output[r] = append(output[r], size-i)
			}
		}
	}
	return output, nil
}

func arrayItoa(input []int) []string {
	var output []string
	for _, i := range input {
		output = append(output, fmt.Sprintf("%4d", i))
	}
	return output
}

func main() {
	data, err := setupMagicSquareData(dimensions)
	if err != nil {
		log.Fatal(err)
	}
	magicConstant := (dimensions * (dimensions*dimensions + 1)) / 2
	for _, row := range data {
		fmt.Println(strings.Join(arrayItoa(row), " "))
	}
	fmt.Printf("\nMagic Constant: %d\n", magicConstant)
}
Output:
   1    2   62   61   60   59    7    8
   9   10   54   53   52   51   15   16
  48   47   19   20   21   22   42   41
  40   39   27   28   29   30   34   33
  32   31   35   36   37   38   26   25
  24   23   43   44   45   46   18   17
  49   50   14   13   12   11   55   56
  57   58    6    5    4    3   63   64

Magic Constant: 260

Haskell

import Data.List (transpose, unfoldr, intercalate)
import Data.List.Split (chunksOf)
import Data.Bool (bool)
import Control.Monad (forM_)

magicSquare :: Int -> [[Int]]
magicSquare n
  | rem n 4 > 0 = []
  | otherwise =
    chunksOf n $ zipWith (flip (bool =<< (-) limit)) series [1 .. sqr]
  where
    sqr = n * n
    limit = sqr + 1
    series
      | isPowerOf 2 n = magicSeries $ floor (logBase 2 (fromIntegral sqr))
      | otherwise =
        concat . concat . concat . scale $ scale <$> chunksOf 4 (magicSeries 4)
      where
        scale = replicate $ quot n 4

magicSeries :: Int -> [Bool]
magicSeries = (iterate ((++) <*> fmap not) [True] !!)

isPowerOf :: Int -> Int -> Bool
isPowerOf k n = until ((0 /=) . flip rem k) (`quot` k) n == 1

-- TEST AND DISPLAY FUNCTIONS --------------------------------------------------
checked :: [[Int]] -> (Int, Bool)
checked square =
  let diagonals =
        fmap (flip (zipWith (!!)) [0 ..]) . ((:) <*> (return . reverse))
      h:t =
        sum <$>
        square ++ -- rows
        transpose square ++ -- cols
        diagonals square -- diagonals
  in (h, all (h ==) t)

table :: String -> [[String]] -> [String]
table delim rows =
  let justifyRight c n s = drop (length s) (replicate n c ++ s)
  in intercalate delim <$>
     transpose
       ((fmap =<< justifyRight ' ' . maximum . fmap length) <$> transpose rows)

main :: IO ()
main =
  forM_ [4, 8, 16] $
  \n -> do
    let test = magicSquare n
    putStrLn $ unlines (table " " (fmap show <$> test))
    print $ checked test
    putStrLn []
Output:
 1 15 14  4
12  6  7  9
 8 10 11  5
13  3  2 16

(34,True)

 1 63 62  4 60  6  7 57
56 10 11 53 13 51 50 16
48 18 19 45 21 43 42 24
25 39 38 28 36 30 31 33
32 34 35 29 37 27 26 40
41 23 22 44 20 46 47 17
49 15 14 52 12 54 55  9
 8 58 59  5 61  3  2 64

(260,True)

  1 255 254   4 252   6   7 249 248  10  11 245  13 243 242  16
240  18  19 237  21 235 234  24  25 231 230  28 228  30  31 225
224  34  35 221  37 219 218  40  41 215 214  44 212  46  47 209
 49 207 206  52 204  54  55 201 200  58  59 197  61 195 194  64
192  66  67 189  69 187 186  72  73 183 182  76 180  78  79 177
 81 175 174  84 172  86  87 169 168  90  91 165  93 163 162  96
 97 159 158 100 156 102 103 153 152 106 107 149 109 147 146 112
144 114 115 141 117 139 138 120 121 135 134 124 132 126 127 129
128 130 131 125 133 123 122 136 137 119 118 140 116 142 143 113
145 111 110 148 108 150 151 105 104 154 155 101 157  99  98 160
161  95  94 164  92 166 167  89  88 170 171  85 173  83  82 176
 80 178 179  77 181  75  74 184 185  71  70 188  68 190 191  65
193  63  62 196  60 198 199  57  56 202 203  53 205  51  50 208
 48 210 211  45 213  43  42 216 217  39  38 220  36 222 223  33
 32 226 227  29 229  27  26 232 233  23  22 236  20 238 239  17
241  15  14 244  12 246 247   9   8 250 251   5 253   3   2 256

(2056,True)

J

masksq=: >:@#@, | _1&^ * 1 + i.@$
pat4=: ,:(+.|.)=i.4
mask=: ,/@(,./"3@$&pat4)@] ,~ % 4:
demsq=: masksq@mask
Output:
   demsq 8
64  2  3 61 60  6  7 57
 9 55 54 12 13 51 50 16
17 47 46 20 21 43 42 24
40 26 27 37 36 30 31 33
32 34 35 29 28 38 39 25
41 23 22 44 45 19 18 48
49 15 14 52 53 11 10 56
 8 58 59  5  4 62 63  1
   ~.(+/,&,+/"1)demsq 128
1048640

Java

public class MagicSquareDoublyEven {

    public static void main(String[] args) {
        int n = 8;
        for (int[] row : magicSquareDoublyEven(n)) {
            for (int x : row)
                System.out.printf("%2s ", x);
            System.out.println();
        }
        System.out.printf("\nMagic constant: %d ", (n * n + 1) * n / 2);
    }

    static int[][] magicSquareDoublyEven(final int n) {
        if (n < 4 || n % 4 != 0)
            throw new IllegalArgumentException("base must be a positive "
                    + "multiple of 4");

        // pattern of count-up vs count-down zones
        int bits = 0b1001_0110_0110_1001;
        int size = n * n;
        int mult = n / 4;  // how many multiples of 4

        int[][] result = new int[n][n];

        for (int r = 0, i = 0; r < n; r++) {
            for (int c = 0; c < n; c++, i++) {
                int bitPos = c / mult + (r / mult) * 4;
                result[r][c] = (bits & (1 << bitPos)) != 0 ? i + 1 : size - i;
            }
        }
        return result;
    }
}
 1  2 62 61 60 59  7  8 
 9 10 54 53 52 51 15 16 
48 47 19 20 21 22 42 41 
40 39 27 28 29 30 34 33 
32 31 35 36 37 38 26 25 
24 23 43 44 45 46 18 17 
49 50 14 13 12 11 55 56 
57 58  6  5  4  3 63 64 

Magic constant: 260

JavaScript

ES6

Translation of: Haskell
(() => {
    'use strict';

    // doublyEvenMagicSquare :: Int -> [[Int]]
    const doublyEvenMagicSquare = n =>
        0 === n % 4 ? (() => {
            const
                sqr = n * n,
                power = Math.log2(sqr),
                scale = replicate(n / 4);
            return chunksOf(n)(
                map((x, i) => x ? 1 + i : sqr - i)(
                    isInt(power) ? truthSeries(power) : (
                        compose(
                            flatten,
                            scale,
                            map(scale),
                            chunksOf(4)
                        )(truthSeries(4))
                    )
                )
            );
        })() : undefined;

    // truthSeries :: Int -> [Bool]
    const truthSeries = n =>
        0 >= n ? (
            [true]
        ) : (() => {
            const xs = truthSeries(n - 1);
            return xs.concat(xs.map(x => !x));
        })();



    // TEST -----------------------------------------------
    const main = () =>
        // Magic squares of orders 4, 8 and 12, with
        // checks of row, column and diagonal sums.
        intercalate('\n\n')(
            map(n => {
                const
                    lines = doublyEvenMagicSquare(n),
                    sums = map(sum)(
                        lines.concat(
                            transpose(lines)
                            .concat(diagonals(lines))
                        )
                    ),
                    total = sums[0];
                return unlines([
                    "Order: " + str(n),
                    "Summing to: " + str(total),
                    "Row, column and diagonal sums checked: " +
                    str(all(eq(total))(sums)) + '\n',
                    unlines(map(compose(
                        intercalate('  '),
                        map(compose(justifyRight(3)(' '), str))
                    ))(lines))
                ]);
            })([4, 8, 12])
        );


    // GENERIC FUNCTIONS ----------------------------------

    // all :: (a -> Bool) -> [a] -> Bool
    const all = p =>
        // True if p(x) holds for every x in xs.
        xs => xs.every(p);

    // chunksOf :: Int -> [a] -> [[a]]
    const chunksOf = n => xs =>
        enumFromThenTo(0)(n)(
            xs.length - 1
        ).reduce(
            (a, i) => a.concat([xs.slice(i, (n + i))]),
            []
        );

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        x => fs.reduceRight((a, f) => f(a), x);

    // diagonals :: [[a]] -> [[a], [a]]
    const diagonals = rows =>
        // Two diagonal sequences,
        // from top left and bottom left
        // respectively, of a given matrix.
        map(flip(zipWith(index))(
            enumFromTo(0)(pred(
                0 < rows.length ? (
                    rows[0].length
                ) : 0
            ))
        ))([rows, reverse(rows)]);

    // enumFromThenTo :: Int -> Int -> Int -> [Int]
    const enumFromThenTo = x1 => x2 => y => {
        const d = x2 - x1;
        return Array.from({
            length: Math.floor(y - x2) / d + 2
        }, (_, i) => x1 + (d * i));
    };

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m => n =>
        Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);

    // eq (==) :: Eq a => a -> a -> Bool
    const eq = a => b => a === b;

    // flatten :: NestedList a -> [a]
    const flatten = nest => nest.flat(Infinity);

    // flip :: (a -> b -> c) -> b -> a -> c
    const flip = f =>
        x => y => f(y)(x);

    // index (!!) :: [a] -> Int -> a
    const index = xs => i => xs[i];

    // intercalate :: String -> [String] -> String
    const intercalate = s =>
        xs => xs.join(s);

    // isInt :: Int -> Bool
    const isInt = x => x === Math.floor(x);

    // justifyRight :: Int -> Char -> String -> String
    const justifyRight = n => cFiller => s =>
        n > s.length ? (
            s.padStart(n, cFiller)
        ) : s;

    // map :: (a -> b) -> [a] -> [b]
    const map = f => xs =>
        (Array.isArray(xs) ? (
            xs
        ) : xs.split('')).map(f);

    // pred :: Enum a => a -> a
    const pred = x => x - 1;

    // replicate :: Int -> a -> [a]
    const replicate = n => x =>
        Array.from({
            length: n
        }, () => x);

    // reverse :: [a] -> [a]
    const reverse = xs =>
        'string' !== typeof xs ? (
            xs.slice(0).reverse()
        ) : xs.split('').reverse().join('');

    // show :: a -> String
    const show = x => JSON.stringify(x);

    // str :: a -> String
    const str = x => x.toString();

    // sum :: [Num] -> Num
    const sum = xs => xs.reduce((a, x) => a + x, 0);

    // transpose :: [[a]] -> [[a]]
    const transpose = xs =>
        xs[0].map((_, iCol) => xs.map((row) => row[iCol]));

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f => xs => ys =>
        xs.slice(
            0, Math.min(xs.length, ys.length)
        ).map((x, i) => f(x)(ys[i]));

    // MAIN ------------------------------------------------
    return main();
})();
Output:
Order: 4
Summing to: 34
Row, column and diagonal sums checked: true

  1   15   14    4
 12    6    7    9
  8   10   11    5
 13    3    2   16

Order: 8
Summing to: 260
Row, column and diagonal sums checked: true

  1   63   62    4   60    6    7   57
 56   10   11   53   13   51   50   16
 48   18   19   45   21   43   42   24
 25   39   38   28   36   30   31   33
 32   34   35   29   37   27   26   40
 41   23   22   44   20   46   47   17
 49   15   14   52   12   54   55    9
  8   58   59    5   61    3    2   64

Order: 12
Summing to: 870
Row, column and diagonal sums checked: true

  1  143  142    4    5  139  138    8    9  135  134   12
132   14   15  129  128   18   19  125  124   22   23  121
120   26   27  117  116   30   31  113  112   34   35  109
 37  107  106   40   41  103  102   44   45   99   98   48
 49   95   94   52   53   91   90   56   57   87   86   60
 84   62   63   81   80   66   67   77   76   70   71   73
 72   74   75   69   68   78   79   65   64   82   83   61
 85   59   58   88   89   55   54   92   93   51   50   96
 97   47   46  100  101   43   42  104  105   39   38  108
 36  110  111   33   32  114  115   29   28  118  119   25
 24  122  123   21   20  126  127   17   16  130  131   13
133   11   10  136  137    7    6  140  141    3    2  144

jq

Translation of: Wren
Works with: jq

Works with gojq, the Go implementation of jq

def lpad($len):
  def l: tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
  if type == "array" then map(l) else l end;

def magicSquareDoublyEven:
  if . < 4 or .%4 != 0 then "Base must be a positive multiple of 4" | error else . end
  | . as $n
  # pattern of count-up vs count-down zones
  | [1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1] as $bits
  | ($n * $n) as $size
  | ($n / 4 | floor) as $mult # how many multiples of 4
  | { i:0, result: null }
  | reduce range(0; $n) as $r (.;
      reduce range(0; $n) as $c (.;
         ( (($c/$mult)|floor) + (($r/$mult)|floor) * 4) as $bitPos
         | .result[$r][$c] =
	      (if ($bits[$bitPos] != 0) then .i + 1 else $size - .i end)
         | .i += 1 ) )
  | .result ;

# Input: the order
def task:
  . as $n
  | (.*.|tostring|length+1) as $width
  | (magicSquareDoublyEven[] | lpad($width) | join(" ")),
    "\nMagic constant for order \($n): \(($n*$n + 1) * $n / 2)\n\n" ;

8, 12 | task
Output:
  1   2  62  61  60  59   7   8
  9  10  54  53  52  51  15  16
 48  47  19  20  21  22  42  41
 40  39  27  28  29  30  34  33
 32  31  35  36  37  38  26  25
 24  23  43  44  45  46  18  17
 49  50  14  13  12  11  55  56
 57  58   6   5   4   3  63  64

Magic constant for order 8: 260


   1    2    3  141  140  139  138  137  136   10   11   12
  13   14   15  129  128  127  126  125  124   22   23   24
  25   26   27  117  116  115  114  113  112   34   35   36
 108  107  106   40   41   42   43   44   45   99   98   97
  96   95   94   52   53   54   55   56   57   87   86   85
  84   83   82   64   65   66   67   68   69   75   74   73
  72   71   70   76   77   78   79   80   81   63   62   61
  60   59   58   88   89   90   91   92   93   51   50   49
  48   47   46  100  101  102  103  104  105   39   38   37
 109  110  111   33   32   31   30   29   28  118  119  120
 121  122  123   21   20   19   18   17   16  130  131  132
 133  134  135    9    8    7    6    5    4  142  143  144

Magic constant for order 12: 870

Julia

using Printf

function magicsquaredoubleeven(order::Int)
    if order % 4 != 0; error("the order must be divisible by 4") end

    sqr = Matrix{Int}(order, order)
    mul = div(order, 4)
    ext = vcat(1:mul, order-mul+1:order)
    isext(i::Int, j::Int) = (i in ext) == (j in ext)
    boolsqr = collect(isext(i, j) for i in 1:order, j in 1:order)
    for i in linearindices(sqr)
        if boolsqr[i]; sqr[i] = i end
        if !boolsqr[end+1-i]; sqr[end+1-i] = i end
    end
    return sqr
end

for n in (4, 8, 12)
    magicconst = div(n ^ 3 + n, 2)
    sq = magicsquaredoubleeven(n)

    println("Order: $n; magic constant: $magicconst.\nSquare:")
    for r in 1:n, c in 1:n
        @printf("%4i", sq[r, c])
        if c == n; println() end
    end
    println()
end
Output:
Order: 4; magic constant: 34.
Square:
   1  12   8  13
  15   6  10   3
  14   7  11   2
   4   9   5  16

Order: 8; magic constant: 260.
Square:
   1   9  48  40  32  24  49  57
   2  10  47  39  31  23  50  58
  62  54  19  27  35  43  14   6
  61  53  20  28  36  44  13   5
  60  52  21  29  37  45  12   4
  59  51  22  30  38  46  11   3
   7  15  42  34  26  18  55  63
   8  16  41  33  25  17  56  64

Order: 12; magic constant: 870.
Square:
   1  13  25 108  96  84  72  60  48 109 121 133
   2  14  26 107  95  83  71  59  47 110 122 134
   3  15  27 106  94  82  70  58  46 111 123 135
 141 129 117  40  52  64  76  88 100  33  21   9
 140 128 116  41  53  65  77  89 101  32  20   8
 139 127 115  42  54  66  78  90 102  31  19   7
 138 126 114  43  55  67  79  91 103  30  18   6
 137 125 113  44  56  68  80  92 104  29  17   5
 136 124 112  45  57  69  81  93 105  28  16   4
  10  22  34  99  87  75  63  51  39 118 130 142
  11  23  35  98  86  74  62  50  38 119 131 143
  12  24  36  97  85  73  61  49  37 120 132 144

Kotlin

Translation of: Java
// version 1.1.0

fun magicSquareDoublyEven(n: Int): Array<IntArray> {
    if ( n < 4 || n % 4 != 0) 
        throw IllegalArgumentException("Base must be a positive multiple of 4")

    // pattern of count-up vs count-down zones
    val bits = 0b1001_0110_0110_1001
    val size = n * n
    val mult = n / 4  // how many multiples of 4 
    val result = Array(n) { IntArray(n) }
    var i = 0
    for (r in 0 until n)
        for (c in 0 until n) {
            val bitPos = c / mult + r / mult * 4
            result[r][c] =  if (bits and (1 shl bitPos) != 0) i + 1 else size - i
            i++
        }
    return result
} 

fun main(args: Array<String>) {
    val n = 8
    for (ia in magicSquareDoublyEven(n)) { 
        for (i in ia) print("%2d  ".format(i))
        println()
    }
    println("\nMagic constant ${(n * n + 1) * n / 2}")
}
Output:
 1   2  62  61  60  59   7   8
 9  10  54  53  52  51  15  16
48  47  19  20  21  22  42  41
40  39  27  28  29  30  34  33
32  31  35  36  37  38  26  25
24  23  43  44  45  46  18  17
49  50  14  13  12  11  55  56
57  58   6   5   4   3  63  64

Magic constant 260

Lua

For all three kinds of Magic Squares(Odd, singly and doubly even)
See Magic_squares/Lua.

Nim

Translation of: Kotlin
import bitops, sequtils, strutils

type Square = seq[seq[int]]

func magicSquareDoublyEven(n: int): Square =
  ## Build a magic square of doubly even order.

  assert n >= 4 and (n and 3) == 0, "base must be a positive multiple of 4."
  result = newSeqWith(n, newSeq[int](n))

  const bits = 0b1001_0110_0110_1001  # Pattern of count-up vs count-down zones.
  let size = n * n
  let mult = n div 4                  # How many multiples of 4.

  var i = 0
  for r in 0..<n:
    for c in 0..<n:
      let bitPos = c div mult + r div mult * 4
      result[r][c] = if bits.testBit(bitPos): i + 1 else: size - i
      inc i


func `$`(square: Square): string =
  ## Return the string representation of a magic square.
  let length = len($(square.len * square.len))
  for row in square:
    result.add row.mapIt(($it).align(length)).join(" ") & '\n'


when isMainModule:
  let n = 8
  echo magicSquareDoublyEven(n)
  echo "Magic constant = ", n * (n * n + 1) div 2
Output:
 1  2 62 61 60 59  7  8
 9 10 54 53 52 51 15 16
48 47 19 20 21 22 42 41
40 39 27 28 29 30 34 33
32 31 35 36 37 38 26 25
24 23 43 44 45 46 18 17
49 50 14 13 12 11 55 56
57 58  6  5  4  3 63 64

Magic constant = 260

PARI/GP

A magic one-liner:

magicsquare(n)=matrix(n,n,i,j,k=i+j*n-n;if(bitand(38505,2^((j-1)%4*4+(i-1)%4)),k,n*n+1-k))

Output:

magicsquare(8)

[ 1 56 48 25 33 24 16 57]

[63 10 18 39 31 42 50  7]

[62 11 19 38 30 43 51  6]

[ 4 53 45 28 36 21 13 60]

[ 5 52 44 29 37 20 12 61]

[59 14 22 35 27 46 54  3]

[58 15 23 34 26 47 55  2]

[ 8 49 41 32 40 17  9 64]

BTW: The bit field number 38505 = 9669h seems to come from hell to do the magic...

Perl

See Magic squares/Perl for a general magic square generator.

Phix

Translation of: C++
with javascript_semantics
constant t = {{1,1,0,0},
              {1,1,0,0},
              {0,0,1,1},
              {0,0,1,1}}
 
function magic_square(integer n)
    if n<4 or mod(n,4)!=0 then return false end if
    sequence square = repeat(repeat(0,n),n)
    integer i = 0
    for r=1 to n do
        for c=1 to n do
            square[r,c] = iff(t[mod(r,4)+1,mod(c,4)+1]?i+1:n*n-i)
            i += 1
        end for
    end for
    return square
end function
 
procedure check(sequence sq)
    integer n = length(sq)
    integer magic = n*(n*n+1)/2
    integer bd = 0, fd = 0
    for i=1 to length(sq) do
        if sum(sq[i])!=magic then ?9/0 end if
        if sum(columnize(sq,i))!=magic then ?9/0 end if
        bd += sq[i,i]
        fd += sq[n-i+1,n-i+1]
    end for
    if bd!=magic or fd!=magic then ?9/0 end if
end procedure
 
--for i=4 to 16 by 4 do
for i=8 to 8 by 4 do
    sequence square = magic_square(i)
    printf(1,"maqic square of order %d, sum: %d\n", {i,sum(square[i])})
    string fmt = sprintf("%%%dd",length(sprintf("%d",i*i)))
    pp(square,{pp_Nest,1,pp_IntFmt,fmt,pp_StrFmt,3,pp_IntCh,false,pp_Pause,0})
    check(square)
end for
Output:
maqic square of order 8, sum: 260
{{ 1,63,62, 4, 5,59,58, 8},
 {56,10,11,53,52,14,15,49},
 {48,18,19,45,44,22,23,41},
 {25,39,38,28,29,35,34,32},
 {33,31,30,36,37,27,26,40},
 {24,42,43,21,20,46,47,17},
 {16,50,51,13,12,54,55, 9},
 {57, 7, 6,60,61, 3, 2,64}}

PureBasic

Translation of: FreeBasic
Procedure.i MagicN(n.i)
  ProcedureReturn n*(n*n+1)/2
EndProcedure

Procedure.i MaxN(mx.i,n.i)
  If mx>n : ProcedureReturn mx : Else : ProcedureReturn n : EndIf
EndProcedure

Procedure.i MaxL(mx.i)
  Define.i i
  While mx
    mx/10 : i+1
  Wend
  ProcedureReturn i
EndProcedure

Procedure.b DblEvenMagicSquare(n.i)
  Define.i q=n/4, nr=1, x, y, max, spc
  Dim sq.i(n,n)
  
  For y=1 To n
    For x=q+1 To n-q
      sq(x,y)=1
    Next
  Next
  
  For x=1 To n
    For y=q+1 To n-q
      sq(x,y) ! 1
    Next
  Next
  
  q=n*n+1
  For y=1 To n
    For x=1 To n
      If sq(x,y)=0
        sq(x,y)=q-nr
      Else
        sq(x,y)=nr
      EndIf
      nr+1
      max=MaxN(max,sq(x,y))
    Next
  Next
  
  spc=MaxL(max)+1
  For y=n To 1 Step -1
    For x=n To 1 Step -1
      Print(RSet(Str(sq(x,y)),spc," "))
    Next
    PrintN("")
  Next
    
EndProcedure

OpenConsole("Magic-Square-Doubly-Even")
Define.i n

Repeat
  PrintN("Input [4,8,12..n] (0=Exit)")
  While (n<4) Or (n%4)
    Print(">") : n=Val(Input())
    If n=0 : End : EndIf
  Wend  
  PrintN("The magic sum = "+Str(MagicN(n)))
  DblEvenMagicSquare(n)  
  n=0
ForEver
Output:
Input [4,8,12..n] (0=Exit)

>8 The magic sum = 260

 1  2 62 61 60 59  7  8
 9 10 54 53 52 51 15 16
48 47 19 20 21 22 42 41
40 39 27 28 29 30 34 33
32 31 35 36 37 38 26 25
24 23 43 44 45 46 18 17
49 50 14 13 12 11 55 56
57 58  6  5  4  3 63 64

Input [4,8,12..n] (0=Exit)

>

Python

Procedural

def MagicSquareDoublyEven(order):
    sq = [range(1+n*order,order + (n*order)+1) for n in range(order) ]
    n1 = order/4
    for r in range(n1):
        r1 = sq[r][n1:-n1]
        r2 = sq[order -r - 1][n1:-n1]
        r1.reverse()
        r2.reverse()
        sq[r][n1:-n1] = r2
        sq[order -r - 1][n1:-n1] = r1
    for r in range(n1, order-n1):
        r1 = sq[r][:n1]
        r2 = sq[order -r - 1][order-n1:]
        r1.reverse()
        r2.reverse()
        sq[r][:n1] = r2
        sq[order -r - 1][order-n1:] = r1
    return sq

def printsq(s):
    n = len(s)
    bl = len(str(n**2))+1
    for i in range(n):
        print ''.join( [ ("%"+str(bl)+"s")%(str(x)) for x in s[i]] )
    print "\nMagic constant = %d"%sum(s[0])

printsq(MagicSquareDoublyEven(8))
Output:

 1  2 62 61 60 59  7  8
 9 10 54 53 52 51 15 16
48 47 19 20 21 22 42 41
40 39 27 28 29 30 34 33
32 31 35 36 37 38 26 25
24 23 43 44 45 46 18 17
49 50 14 13 12 11 55 56
57 58  6  5  4  3 63 64

Magic constant = 260

>>>


Composition of pure functions

Generating test results and a magic square in the form of a wiki table:

Works with: Python version 3.7
'''Magic squares of doubly even order'''

from itertools import chain, repeat
from functools import reduce
from math import log


# doublyEvenMagicSquare :: Int -> [[Int]]
def doublyEvenMagicSquare(n):
    '''Magic square of order n'''

    # magic :: Int -> [Bool]
    def magic(n):
        '''Truth-table series'''
        if 0 < n:
            xs = magic(n - 1)
            return xs + [not x for x in xs]
        else:
            return [True]

    sqr = n * n
    power = log(sqr, 2)
    scale = replicate(n / 4)
    return chunksOf(n)([
        succ(i) if bln else sqr - i for i, bln in
        enumerate(magic(power) if isInteger(power) else (
            flatten(scale(
                map(scale, chunksOf(4)(magic(4)))
            ))
        ))
    ])


# TEST ----------------------------------------------------
# main :: IO()
def main():
    '''Tests'''

    order = 8
    magicSquare = doublyEvenMagicSquare(order)

    print(
        'Row sums: ',
        [sum(xs) for xs in magicSquare],
        '\nCol sums:',
        [sum(xs) for xs in transpose(magicSquare)],
        '\n1st diagonal sum:',
        sum(magicSquare[i][i] for i in range(0, order)),
        '\n2nd diagonal sum:',
        sum(magicSquare[i][(order - 1) - i] for i in range(0, order)),
        '\n'
    )
    print(wikiTable({
        'class': 'wikitable',
        'style': cssFromDict({
            'text-align': 'center',
            'color': '#605B4B',
            'border': '2px solid silver'
        }),
        'colwidth': '3em'
    })(magicSquare))


# GENERIC -------------------------------------------------


# chunksOf :: Int -> [a] -> [[a]]
def chunksOf(n):
    '''A series of lists of length n,
       subdividing the contents of xs.
       Where the length of xs is not evenly divible
       the final list will be shorter than n.'''
    return lambda xs: reduce(
        lambda a, i: a + [xs[i:n + i]],
        range(0, len(xs), n), []
    ) if 0 < n else []


# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
    '''Concatenated list over which a function has been mapped.
       The list monad can be derived by using a function f which
       wraps its output a in list
       (using an empty list to represent computational failure).'''
    return lambda xs: list(
        chain.from_iterable(
            map(f, xs)
        )
    )


# cssFromDict :: Dict -> String
def cssFromDict(dct):
    '''CSS string serialized from key values in a Dictionary.'''
    return reduce(
        lambda a, k: a + k + ':' + dct[k] + '; ', dct.keys(), ''
    )


# flatten :: NestedList a -> [a]
def flatten(x):
    '''A list of atoms resulting from fully flattening
       an arbitrarily nested list.'''
    return concatMap(flatten)(x) if isinstance(x, list) else [x]


# isInteger :: Num -> Bool
def isInteger(n):
    '''Divisible by one without remainder ?'''
    return 0 == (n - int(n))


# replicate :: Int -> a -> [a]
def replicate(n):
    '''A list of length n in which every element
       has the value x.'''
    return lambda x: list(repeat(x, n))


# succ :: Enum a => a -> a
def succ(x):
    '''The successor of a value. For numeric types, (1 +).'''
    return 1 + x if isinstance(x, int) else (
        chr(1 + ord(x))
    )


# transpose :: Matrix a -> Matrix a
def transpose(m):
    '''The rows and columns of the argument transposed.
       (The matrix containers and rows can be lists or tuples).'''
    if m:
        inner = type(m[0])
        z = zip(*m)
        return (type(m))(
            map(inner, z) if tuple != inner else z
        )
    else:
        return m


# wikiTable :: Dict -> [[a]] -> String
def wikiTable(opts):
    '''List of lists rendered as a wiki table string.'''
    def colWidth():
        return 'width:' + opts['colwidth'] + '; ' if (
            'colwidth' in opts
        ) else ''

    def cellStyle():
        return opts['cell'] if 'cell' in opts else ''

    return lambda rows: '{| ' + reduce(
        lambda a, k: (
            a + k + '="' + opts[k] + '" ' if k in opts else a
        ),
        ['class', 'style'],
        ''
    ) + '\n' + '\n|-\n'.join(
        '\n'.join(
            ('|' if (0 != i and ('cell' not in opts)) else (
                '|style="' + colWidth() + cellStyle() + '"|'
            )) + (
                str(x) or ' '
            ) for x in row
        ) for i, row in enumerate(rows)
    ) + '\n|}\n\n'


if __name__ == '__main__':
    main()
Output:
Row sums:  [260, 260, 260, 260, 260, 260, 260, 260] 
Col sums: [260, 260, 260, 260, 260, 260, 260, 260] 
1st diagonal sum: 260 
2nd diagonal sum: 260 
1 63 62 4 60 6 7 57
56 10 11 53 13 51 50 16
48 18 19 45 21 43 42 24
25 39 38 28 36 30 31 33
32 34 35 29 37 27 26 40
41 23 22 44 20 46 47 17
49 15 14 52 12 54 55 9
8 58 59 5 61 3 2 64

R

Translation of the magic square code example from Jama, which is released to the public domain. This includes all three cases.

magic <- function(n) {
  if (n %% 2 == 1) {
    p <- (n + 1) %/% 2 - 2
    ii <- seq(n)
    outer(ii, ii, function(i, j) n * ((i + j + p) %% n) + (i + 2 * (j - 1)) %% n + 1)
  } else if (n %% 4 == 0) {
    p <- n * (n + 1) + 1
    ii <- seq(n)
    outer(ii, ii, function(i, j) ifelse((i %/% 2 - j %/% 2) %% 2 == 0, p - n * i - j, n * (i - 1) + j))
  } else {
    p <- n %/% 2
    q <- p * p
    k <- (n - 2) %/% 4 + 1
    a <- Recall(p)
    a <- rbind(cbind(a, a + 2 * q), cbind(a + 3 * q, a + q))
    ii <- seq(p)
    jj <- c(seq(k - 1), seq(length.out=k - 2, to=n))
    m <- a[ii, jj]; a[ii, jj] <- a[ii + p, jj]; a[ii + p, jj] <- m
    jj <- c(1, k)
    m <- a[k, jj]; a[k, jj] <- a[k + p, jj]; a[k + p, jj] <- m
    a
  }
}

Example

> magic(8)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]   64    2    3   61   60    6    7   57
[2,]    9   55   54   12   13   51   50   16
[3,]   17   47   46   20   21   43   42   24
[4,]   40   26   27   37   36   30   31   33
[5,]   32   34   35   29   28   38   39   25
[6,]   41   23   22   44   45   19   18   48
[7,]   49   15   14   52   53   11   10   56
[8,]    8   58   59    5    4   62   63    1

Raku

(formerly Perl 6)

See Magic squares/Raku for a general magic square generator.

Output:

With a parameter of 8:

 1  2 62 61 60 59  7  8
 9 10 54 53 52 51 15 16
48 47 19 20 21 22 42 41
40 39 27 28 29 30 34 33
32 31 35 36 37 38 26 25
24 23 43 44 45 46 18 17
49 50 14 13 12 11 55 56
57 58  6  5  4  3 63 64

The magic number is 260

With a parameter of 12:

  1   2   3 141 140 139 138 137 136  10  11  12
 13  14  15 129 128 127 126 125 124  22  23  24
 25  26  27 117 116 115 114 113 112  34  35  36
108 107 106  40  41  42  43  44  45  99  98  97
 96  95  94  52  53  54  55  56  57  87  86  85
 84  83  82  64  65  66  67  68  69  75  74  73
 72  71  70  76  77  78  79  80  81  63  62  61
 60  59  58  88  89  90  91  92  93  51  50  49
 48  47  46 100 101 102 103 104 105  39  38  37
109 110 111  33  32  31  30  29  28 118 119 120
121 122 123  21  20  19  18  17  16 130 131 132
133 134 135   9   8   7   6   5   4 142 143 144

The magic number is 870

REXX

"Marked" numbers   (via the   diag   subroutine)   indicate that those (sequentially generated) numbers don't get
swapped   (and thusly, stay in place in the magic square).

/*REXX program constructs a  magic square  of doubly even sides (a size divisible by 4).*/
n= 8;   s= n%4;   L= n%2-s+1;    w= length(n**2) /*size; small sq;  low middle;  # width*/
@.= 0;            H= n%2+s                       /*array default;  high middle.         */
call gen                                         /*generate a grid in numerical order.  */
call diag                                        /*mark numbers on both diagonals.      */
call corn                                        /*  "     "    in small corner boxen.  */
call midd                                        /*  "     "    in  the middle    "     */
call swap                                        /*swap positive numbers with highest #.*/
call show                                        /*display the doubly even magic square.*/
call sum                                         /*   "     "  magic number for square. */
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
o:    parse arg ?;             return n-?+1      /*calculate the "other" (right) column.*/
@:    parse arg x,y;           return abs(@.x.y)
diag:      do r=1 for n;  @.r.r=-@(r,r); o=o(r);  @.r.o=-@(r,o);  end;              return
midd:      do r=L  to H;  do c=L  to H;  @.r.c=-@(r,c);           end;  end;        return
gen:  #=0; do r=1 for n;  do c=1  for n; #=#+1;   @.r.c=#;        end;  end;        return
show: #=0; do r=1 for n;  $=; do c=1  for n; $=$ right(@(r,c),w); end;  say $; end; return
sum:  #=0; do r=1 for n;  #=#+@(r,1);  end;  say;  say 'The magic number is: '   #; return
max#:      do a=n for n  by -1;  do b=n  for n  by -1;  if @.a.b>0  then return; end;  end
/*──────────────────────────────────────────────────────────────────────────────────────*/
swap:         do   r=1  for n
                do c=1  for n;  if @.r.c<0  then iterate;  call max#  /*find max number.*/
                parse value  -@.a.b  (-@.r.c)    with    @.r.c  @.a.b /*swap two values.*/
                end   /*c*/
              end     /*r*/;                       return
/*──────────────────────────────────────────────────────────────────────────────────────*/
corn:         do   r=1  for n;  if r>s & r<=n-s  then iterate   /*"corner boxen", size≡S*/
                do c=1  for n;  if c>s & c<=n-s  then iterate;  @.r.c= -@(r,c)  /*negate*/
                end   /*c*/
              end     /*r*/;                       return
output   when using the default input:
  1  2 62 61 60 59  7  8
  9 10 54 53 52 51 15 16
 48 47 19 20 21 22 42 41
 40 39 27 28 29 30 34 33
 32 31 35 36 37 38 26 25
 24 23 43 44 45 46 18 17
 49 50 14 13 12 11 55 56
 57 58  6  5  4  3 63 64

The magic number is:  260

Ruby

def double_even_magic_square(n)
  raise ArgumentError, "Need multiple of four" if n%4 > 0
  block_size, max = n/4, n*n
  pre_pat = [true, false, false, true,
             false, true, true, false]
  pre_pat += pre_pat.reverse
  pattern = pre_pat.flat_map{|b| [b] * block_size} * block_size
  flat_ar = pattern.each_with_index.map{|yes, num| yes ? num+1 : max-num}
  flat_ar.each_slice(n).to_a
end

def to_string(square)
  n = square.size
  fmt = "%#{(n*n).to_s.size + 1}d" * n
  square.inject(""){|str,row| str << fmt % row << "\n"}
end

puts to_string(double_even_magic_square(8))
Output:
  1  2 62 61 60 59  7  8
 56 55 11 12 13 14 50 49
 48 47 19 20 21 22 42 41
 25 26 38 37 36 35 31 32
 33 34 30 29 28 27 39 40
 24 23 43 44 45 46 18 17
 16 15 51 52 53 54 10  9
 57 58  6  5  4  3 63 64

Rust

use std::env;

fn main() {
    let n: usize = match env::args()
        .nth(1)
        .and_then(|arg| arg.parse().ok())
        .ok_or("Please specify the size of the magic square, as a positive multiple of 4.")
    {
        Ok(arg) if arg >= 4 && arg % 4 == 0 => arg,
        Err(e) => panic!(e),
        _ => panic!("Argument must be a positive multiple of 4."),
    };

    let mc = (n * n + 1) * n / 2;
    println!("Magic constant: {}\n", mc);
    let bits = 0b1001_0110_0110_1001u32;
    let size = n * n;
    let width = size.to_string().len() + 1;
    let mult = n / 4;
    let mut i = 0;
    for r in 0..n {
        for c in 0..n {
            let bit_pos = c / mult + (r / mult) * 4;
            print!(
                "{e:>w$}",
                e = if bits & (1 << bit_pos) != 0 {
                    i + 1
                } else {
                    size - i
                },
                w = width
            );
            i += 1;
        }
        println!();
    }
}
Output:
Magic constant: 260

  1  2 62 61 60 59  7  8
  9 10 54 53 52 51 15 16
 48 47 19 20 21 22 42 41
 40 39 27 28 29 30 34 33
 32 31 35 36 37 38 26 25
 24 23 43 44 45 46 18 17
 49 50 14 13 12 11 55 56
 57 58  6  5  4  3 63 64

Scala

Output:

Best seen running in your browser either by ScalaFiddle (ES aka JavaScript, non JVM) or Scastie (remote JVM).

object MagicSquareDoublyEven extends App {
  private val n = 8

  private def magicSquareDoublyEven(n: Int): Array[Array[Int]] = {
    require(n >= 4 || n % 4 == 0, "Base must be a positive multiple of 4.")

    // pattern of count-up vs count-down zones
    val (bits, mult, result, size) = (38505, n / 4, Array.ofDim[Int](n, n), n * n)
    var i = 0

    for (r <- result.indices; c <- result(0).indices) {
      def bitPos = c / mult + (r / mult) * 4

      result(r)(c) = if ((bits & (1 << bitPos)) != 0) i + 1 else size - i
      i += 1
    }
    result
  }

  magicSquareDoublyEven(n).foreach(row => println(row.map(x => f"$x%2s ").mkString))
  println(f"---%nMagic constant: ${(n * n + 1) * n / 2}%d")

}

Sidef

Translation of: Ruby
func double_even_magic_square(n) {
    assert(n%4 == 0, "Need multiple of four")
    var (bsize, max) = (n/4, n*n)
    var pre_pat = [true, false, false, true,
                   false, true, true, false]
    pre_pat += pre_pat.flip
    var pattern = (pre_pat.map{|b| bsize.of(b)... } * bsize)
    pattern.map_kv{|k,v| v ? k+1 : max-k }.slices(n)
}

func format_matrix(a) {
    var fmt = "%#{a.len**2 -> len}s"
    a.map { .map { fmt % _ }.join(' ') }.join("\n")
}

say format_matrix(double_even_magic_square(8))
Output:
 1  2 62 61 60 59  7  8
56 55 11 12 13 14 50 49
48 47 19 20 21 22 42 41
25 26 38 37 36 35 31 32
33 34 30 29 28 27 39 40
24 23 43 44 45 46 18 17
16 15 51 52 53 54 10  9
57 58  6  5  4  3 63 64

Stata

Translation of: R
mata
function magic(n) {
    if (mod(n,2)==1) {
        p = (n+1)/2-2
        a = J(n,n,.)
        for (i=1; i<=n; i++) {
            for (j=1; j<=n; j++) {
                a[i,j] = n*mod(i+j+p,n)+mod(i+2*j-2,n)+1
            }
        }
    } else if (mod(n,4)==0) {
        p = n^2+n+1
        a = J(n,n,.)
        for (i=1; i<=n; i++) {
            for (j=1; j<=n; j++) {
                a[i,j] = mod(floor(i/2)-floor(j/2),2)==0 ? p-n*i-j : n*(i-1)+j
            }
        }
    } else {
        p = n/2
        q = p*p
        k = (n-2)/4+1
        a = magic(p)
        a = a,a:+2*q\a:+3*q,a:+q
        i = 1..p
        j = 1..k-1
        if (k>2) j = j,n-k+3..n
        m = a[i,j]; a[i,j] = a[i:+p,j]; a[i:+p,j] = m
        j = 1,k
        m = a[k,j]; a[k,j] = a[k:+p,j]; a[k:+p,j] = m
    }
    return(a)
}
end
. mata magic(8)
        1    2    3    4    5    6    7    8
    +-----------------------------------------+
  1 |  64    2    3   61   60    6    7   57  |
  2 |   9   55   54   12   13   51   50   16  |
  3 |  17   47   46   20   21   43   42   24  |
  4 |  40   26   27   37   36   30   31   33  |
  5 |  32   34   35   29   28   38   39   25  |
  6 |  41   23   22   44   45   19   18   48  |
  7 |  49   15   14   52   53   11   10   56  |
  8 |   8   58   59    5    4   62   63    1  |
    +-----------------------------------------+

VBScript

Translation of: Java
' Magic squares of doubly even order
n=8  'multiple of 4
pattern="1001011001101001"
size=n*n: w=len(size)
mult=n\4  'how many multiples of 4 
wscript.echo "Magic square : " & n & " x " & n
i=0
For r=0 To n-1
	l=""
	For c=0 To n-1
		bit=Mid(pattern, c\mult+(r\mult)*4+1, 1)
		If bit="1" Then t=i+1 Else t=size-i
		l=l & Right(Space(w) & t, w) & " "
		i=i+1
	Next 'c
	wscript.echo l
Next 'r
wscript.echo "Magic constant=" & (n*n+1)*n/2
Output:
Magic square : 8 x 8
 1  2 62 61 60 59  7  8 
 9 10 54 53 52 51 15 16 
48 47 19 20 21 22 42 41 
40 39 27 28 29 30 34 33 
32 31 35 36 37 38 26 25 
24 23 43 44 45 46 18 17 
49 50 14 13 12 11 55 56 
57 58  6  5  4  3 63 64 
Magic constant=260

Visual Basic .NET

Translation of: C#
Module MagicSquares

    Function MagicSquareDoublyEven(n As Integer) As Integer(,)
        If n < 4 OrElse n Mod 4 <> 0 Then
            Throw New ArgumentException("base must be a positive multiple of 4")
        End If

        'pattern of count-up vs count-down zones
        Dim bits = Convert.ToInt32("1001011001101001", 2)
        Dim size = n * n
        Dim mult As Integer = n / 4 ' how many multiples of 4

        Dim result(n - 1, n - 1) As Integer

        Dim i = 0
        For r = 0 To n - 1
            For c = 0 To n - 1
                Dim bitPos As Integer = Math.Floor(c / mult) + Math.Floor(r / mult) * 4
                Dim test = (bits And (1 << bitPos)) <> 0
                If test Then
                    result(r, c) = i + 1
                Else
                    result(r, c) = size - i
                End If

                i = i + 1
            Next
            Console.WriteLine()
        Next

        Return result
    End Function

    Sub Main()
        Dim n = 8
        Dim result = MagicSquareDoublyEven(n)
        For i = 0 To result.GetLength(0) - 1
            For j = 0 To result.GetLength(1) - 1
                Console.Write("{0,2} ", result(i, j))
            Next
            Console.WriteLine()
        Next
        Console.WriteLine()
        Console.WriteLine("Magic constant: {0} ", (n * n + 1) * n / 2)

        Console.ReadLine()
    End Sub

End Module
Output:
 1  2 62 61 60 59  7  8
 9 10 54 53 52 51 15 16
48 47 19 20 21 22 42 41
40 39 27 28 29 30 34 33
32 31 35 36 37 38 26 25
24 23 43 44 45 46 18 17
49 50 14 13 12 11 55 56
57 58  6  5  4  3 63 64

Magic constant: 260

Wren

Translation of: Kotlin
Library: Wren-fmt
import "./fmt" for Conv, Fmt

var magicSquareDoublyEven = Fn.new { |n|
    if (n < 4 || n%4 != 0) Fiber.abort("Base must be a positive multiple of 4")

    // pattern of count-up vs count-down zones
    var bits = Conv.atoi("1001011001101001", 2)
    var size = n * n
    var mult = (n/4).floor // how many multiples of 4
    var result = List.filled(n, null)
    for (i in 0...n) result[i] = List.filled(n, 0)
    var i = 0
    for (r in 0...n) {
        for (c in 0...n) {
            var bitPos = (c/mult).floor + (r/mult).floor * 4
            result[r][c] = ((bits & (1<<bitPos)) != 0) ? i + 1 : size - i
            i = i + 1
        }
    }
    return result
}

var n = 8
for (ia in magicSquareDoublyEven.call(n)) {
    for (i in ia) Fmt.write("$2d  ", i)
    System.print()
}
System.print("\nMagic constant %((n * n + 1) * n / 2)")
Output:
 1   2  62  61  60  59   7   8  
 9  10  54  53  52  51  15  16  
48  47  19  20  21  22  42  41  
40  39  27  28  29  30  34  33  
32  31  35  36  37  38  26  25  
24  23  43  44  45  46  18  17  
49  50  14  13  12  11  55  56  
57  58   6   5   4   3  63  64  

Magic constant 260

XPL0

Translation of: ALGOL 60
    \Magic squares of doubly even order - 11/30/2024;
    integer Pattern(1+4,1+4);
    integer N, R, C, S, M, I, B, T;
begin
    N:=8;
    for R:=1 to 4 do
        for C:=1 to 4 do
            Pattern(R,C):=if 
                ((C=1 or C=4) and (R=1 or R=4)) or
                ((C=2 or C=3) and (R=2 or R=3)) then 1 else 0;
    S:=N*N;  M:=N/4;
    Text(1,"magic square -- n = "); IntOut(1,N); Text(1,"^m^j");
    I:=0;
    for R:=1 to N do begin
        for C:=1 to N do begin
            B:=Pattern((R-1)/M+1, (C-1)/M+1);
            if B=1 then T:=I+1 else T:=S-I;
            if T < 10 then Text(1," ");
            Text(1," ");
            IntOut(1,T);
            I:=I+1
        end;
        Text(1,"^m^j")
    end;
    Text(1,"magic constant = "); IntOut(1,(S+1)*N/2)
end
Output:
magic square -- n = 8
  1  2 62 61 60 59  7  8
  9 10 54 53 52 51 15 16
 48 47 19 20 21 22 42 41
 40 39 27 28 29 30 34 33
 32 31 35 36 37 38 26 25
 24 23 43 44 45 46 18 17
 49 50 14 13 12 11 55 56
 57 58  6  5  4  3 63 64
magic constant = 260

zkl

Translation of: Java
class MagicSquareDoublyEven{
   fcn init(n){ var result=magicSquareDoublyEven(n) }
   fcn toString{
      sink,n:=Sink(String),result.len();  // num collumns
      fmt:="%2s ";
      foreach row in (result)
         { sink.write(row.apply('wrap(n){ fmt.fmt(n) }).concat(),"\n") }
      sink.write("\nMagic constant: %d".fmt((n*n + 1)*n/2));
      sink.close();
   }
   fcn magicSquareDoublyEven(n){
      if (n<4 or n%4!=0 or n>16)
	 throw(Exception.ValueError("base must be a positive multiple of 4"));
      bits,size,mult:=0b1001011001101001, n*n, n/4;
      result:=n.pump(List(),n.pump(List(),0).copy);  // array[n,n] of zero

      foreach i in (size){
	 bitsPos:=(i%n)/mult + (i/(n*mult)*4);
	 value:=(bits.bitAnd((2).pow(bitsPos))) and i+1 or size-i;
	 result[i/n][i%n]=value;
      }
      result;
   }
}
MagicSquareDoublyEven(8).println();
Output:
 1  2 62 61 60 59  7  8 
 9 10 54 53 52 51 15 16 
48 47 19 20 21 22 42 41 
40 39 27 28 29 30 34 33 
32 31 35 36 37 38 26 25 
24 23 43 44 45 46 18 17 
49 50 14 13 12 11 55 56 
57 58  6  5  4  3 63 64 

Magic constant: 260
Cookies help us deliver our services. By using our services, you agree to our use of cookies.