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
 Magic squares of odd order
 Magic squares of singly even order



See also

 Doubly Even Magic Squares (1728.org)


/*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