Magic squares of doubly even order: Difference between revisions

Content added Content deleted
(comment deleted!)
(→‎{{header|Ruby}}: Added Ruby)
Line 405: Line 405:
</pre>
</pre>


=={{header|zkl}}==
=={{header|Ruby}}==
{{trans|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


<lang ruby>def double_even_magic_square(n)
foreach i in (size){
raise ArgumentError, "Need multiple of four" if n%4 > 0
bitsPos:=(i%n)/mult + (i/(n*mult)*4);
block_size, max = n/4, n*n
value:=(bits.bitAnd((2).pow(bitsPos))) and i+1 or size-i;
pre_pat = [true, false, false, true,
result[i/n][i%n]=value;
false, true, true, false]
}
pre_pat += pre_pat.reverse
result;
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
MagicSquareDoublyEven(8).println();</lang>
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))</lang>
{{out}}
{{out}}
<pre>
<pre>
1 2 62 61 60 59 7 8
1 2 62 61 60 59 7 8
9 10 54 53 52 51 15 16
56 55 11 12 13 14 50 49
48 47 19 20 21 22 42 41
48 47 19 20 21 22 42 41
40 39 27 28 29 30 34 33
25 26 38 37 36 35 31 32
32 31 35 36 37 38 26 25
33 34 30 29 28 27 39 40
24 23 43 44 45 46 18 17
24 23 43 44 45 46 18 17
49 50 14 13 12 11 55 56
16 15 51 52 53 54 10 9
57 58 6 5 4 3 63 64
57 58 6 5 4 3 63 64

Magic constant: 260
</pre>
</pre>