Magic squares of doubly even order: Difference between revisions

(comment deleted!)
(→‎{{header|Ruby}}: Added Ruby)
Line 405:
</pre>
 
=={{header|zklRuby}}==
{{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}}
<pre>
1 2 62 61 60 59 7 8
956 1055 5411 5312 5213 5114 15 1650 49
48 47 19 20 21 22 42 41
40 25 3926 2738 2837 2936 3035 34 3331 32
32 33 3134 3530 3629 3728 3827 26 2539 40
24 23 43 44 45 46 18 17
49 16 5015 1451 1352 1253 1154 5510 56 9
57 58 6 5 4 3 63 64
 
Magic constant: 260
</pre>
1,149

edits