Magic squares of doubly even order: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Java}}: small change)
m (→‎{{header|Perl 6}}: Update example)
Line 81: Line 81:


=={{header|Perl 6}}==
=={{header|Perl 6}}==
See [[Magic_squares/Perl_6|Magic squares/Perl 6]]
See [[Magic_squares/Perl_6|Magic squares/Perl 6]] for a general magic square generator. Note that it produces '''a''' magic square, not '''the''' magic square. The output is different each time.
{{out}}
{{out}}
With a parameter of 8:
With a parameter of 8:
<pre> 1 2 62 61 60 59 7 8
<pre>54 16 53 52 10 9 15 51
9 10 54 53 52 51 15 16
27 33 28 29 39 40 34 30
48 47 19 20 21 22 42 41
19 41 20 21 47 48 42 22
40 39 27 28 29 30 34 33
35 25 36 37 31 32 26 38
32 31 35 36 37 38 26 25
62 8 61 60 2 1 7 59
24 23 43 44 45 46 18 17
6 64 5 4 58 57 63 3
49 50 14 13 12 11 55 56
43 17 44 45 23 24 18 46
57 58 6 5 4 3 63 64
14 56 13 12 50 49 55 11


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

The magic number is 870

</pre>


=={{header|REXX}}==
=={{header|REXX}}==

Revision as of 21:34, 17 March 2016

Magic squares of doubly even order is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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


The task: create a magic square of 8 x 8.

Cf.
See also

Java

<lang 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 = 0b1001011001101001;
       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 bitsPos = c / mult + (r / mult) * 4;
               result[r][c] = (bits & (1 << bitsPos)) != 0 ? i + 1 : size - i;
           }
       }
       return result;
   }

}</lang>

 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

Perl 6

See Magic squares/Perl 6 for a general magic square generator. Note that it produces a magic square, not the magic square. The output is different each time.

Output:

With a parameter of 8:

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

The magic number is 260

With a parameter of 12:

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

The magic number is 870

REXX

Marked numbers indicate that those (sequentially generated) numbers don't get swapped   (and thusly, stay in place in the magic square). <lang rexx>/*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 to 1 by -1; do b=n to 1 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);  end  /*c*/
             end   /*r*/
     return</lang>

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

zkl

Translation of: Java

<lang zkl>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();</lang>

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