Magic squares/Raku: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Perl 6}}: Generalize the magic squares code)
 
m (→‎{{header|Perl 6}}: Add links to the various tasks)
Line 2: Line 2:
Invoke at the command line and pass in the desired size as a parameter.
Invoke at the command line and pass in the desired size as a parameter.


{{works with|Rakudo|2016-02}}
See:

[[Magic_squares_of_odd_order#Perl_6|Magic squares of odd order#Perl 6]]
See:<ul>
<li>[[Magic_squares_of_odd_order#Perl_6|Magic squares of odd order#Perl 6]]</li>
<li>[[Magic_squares_of_singly_even_order#Perl_6|Magic squares of singly even order#Perl 6]]</li>
<li>[[Magic_squares_of_doubly_even_order#Perl_6|Magic squares of doubly even order#Perl 6]]</li>
</ul>


<lang perl6>sub MAIN (Int $n where {$n > 0}) {
<lang perl6>sub MAIN (Int $n where {$n > 0}) {

Revision as of 01:53, 17 March 2016

Rather than having multiple examples for different orders of magic square, this will generate a magic square for any valid n x n grid. Invoke at the command line and pass in the desired size as a parameter.

Works with: Rakudo version 2016-02

See:

<lang perl6>sub MAIN (Int $n where {$n > 0}) {

   my @sq;
   my $i = 1;
   gen-sq($n);
   say .fmt("%{$i.chars}d", ' ') for @sq;
   say "\nThe magic number is ", [+] @sq[0].list;


   multi sub gen-sq (2) {
       note "Sorry, can not generate a 2 x 2 magic square." and exit;
   }
   multi sub gen-sq ($n where {$n % 2}) {
       my $x = $n/2;
       my $y = 0;
       @sq[($i % $n ?? $y-- !! $y++) % $n][($i % $n ?? $x++ !! $x) % $n] = $i++ for ^($n * $n);
   }
   multi sub gen-sq ($n where {$n %% 4}) {
       my $x = 0;
       my $y = 0;
       @sq[$i % $n ?? $y !! $y++][($i-1) % $n] = $i++ for ^($n * $n);
       my $t;
       for 0 ..^ $n div 4 -> $r {
           for $n div 4 ..^ $n - $n div 4 -> $c {
               (@sq[$r;$c], @sq[$n-1-$r;$n-1-$c]) =
               (@sq[$n-1-$r;$n-1-$c], @sq[$r;$c]);
               (@sq[$c;$r], @sq[$n-1-$c;$n-1-$r]) =
               (@sq[$n-1-$c;$n-1-$r], @sq[$c;$r]);
           }
       }
   }
   multi sub gen-sq ($n where {$n %% 2 and $n % 4}) {
       my $h = $n div 2;
       gen-sq($h);
       $i *= 4;
       for ^$h -> $r {
           for ^$h -> $c {
               @sq[$r + $h;$c] = @sq[$r;$c] + $h² * 3;
               @sq[$r;$c + $h] = @sq[$r;$c] + $h² * 2;
               @sq[$r + $h;$c + $h] = @sq[$r;$c] + $h²;
           }
           for ^(($h-1)/2) -> $c {
               next if $c == 0 and $r == ($h-1) div 2;
               (@sq[$r][$c], @sq[$r + $h][$c]) = (@sq[$r + $h][$c], @sq[$r][$c]);
           }
       }
       (@sq[($h-1)/2][($h-1)/2], @sq[($h-1)/2+$h][($h-1)/2]) =
       (@sq[($h-1)/2+$h][($h-1)/2], @sq[($h-1)/2][($h-1)/2]);
       if $h > 4 {
           for ^$h -> $r {
               for ($n - ($h-3) / 2) ..^ $n -> $c {
                   (@sq[$r][$c], @sq[$r + $h][$c]) =
                   (@sq[$r + $h][$c], @sq[$r][$c]);
               }
           }
       }
   }

}</lang>