Magic squares/Raku: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (→{{header|Perl 6}}: Style tweaks) |
Thundergnat (talk | contribs) m (syntax highlighting) |
||
(5 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
Rather than having multiple examples for different orders of magic square, this will generate a magic square for ''any'' valid n x n grid. |
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. |
Invoke at the command line and pass in the desired size as a parameter. |
||
Line 5: | Line 6: | ||
See:<ul> |
See:<ul> |
||
<li>[[Magic_squares_of_odd_order# |
<li>[[Magic_squares_of_odd_order#Raku|Magic squares of odd order#Raku]]</li> |
||
<li>[[Magic_squares_of_singly_even_order# |
<li>[[Magic_squares_of_singly_even_order#Raku|Magic squares of singly even order#Raku]]</li> |
||
<li>[[Magic_squares_of_doubly_even_order# |
<li>[[Magic_squares_of_doubly_even_order#Raku|Magic squares of doubly even order#Raku]]</li> |
||
</ul> |
</ul> |
||
<lang |
<syntaxhighlight lang="raku" line>sub MAIN (Int $n where {$n > 0}) { |
||
my @sq; |
my @sq; |
||
my $i = 1; |
my $i = 1; |
||
⚫ | |||
⚫ | |||
gen-sq($n); |
gen-sq($n); |
||
Line 21: | Line 25: | ||
multi sub gen-sq (2) { |
multi sub gen-sq (2) { # invalid |
||
note "Sorry, can not generate a 2 x 2 magic square." and exit; |
note "Sorry, can not generate a 2 x 2 magic square." and exit; |
||
} |
} |
||
multi sub gen-sq ($n where {$n % 2}) { |
multi sub gen-sq ($n where {$n % 2}) { # odd |
||
my $x = $n/2; |
my $x = $n/2; |
||
my $y = 0; |
my $y = 0; |
||
Line 31: | Line 35: | ||
} |
} |
||
multi sub gen-sq ($n where {$n %% 4}) { |
multi sub gen-sq ($n where {$n %% 4}) { # doubly even |
||
my $x = 0; |
my $x = 0; |
||
my $y = 0; |
my $y = 0; |
||
@sq[$i % $n ?? $y !! $y++][($i-1) % $n] = $i++ for ^$n²; |
@sq[$i % $n ?? $y !! $y++][($i-1) % $n] = $i++ for ^$n²; |
||
for ^$q -> $r { |
|||
for |
for $q ..^ $n - $q -> $c { |
||
my $ŕ = $n - 1 - $r; |
|||
my $ć = $n - 1 - $c; |
|||
(@sq[ |
(@sq[$r;$c], @sq[$ŕ;$ć]) = (@sq[$ŕ;$ć], @sq[$r;$c]); |
||
(@sq[$c;$r], @sq[$ |
(@sq[$c;$r], @sq[$ć;$ŕ]) = (@sq[$ć;$ŕ], @sq[$c;$r]); |
||
⚫ | |||
} |
} |
||
} |
} |
||
} |
} |
||
multi sub gen-sq ($n where {$n %% 2 and $n % 4}) { |
multi sub gen-sq ($n where {$n %% 2 and $n % 4}) { # singly even |
||
⚫ | |||
gen-sq($h); |
gen-sq($h); |
||
$i *= 4; |
$i *= 4; |
||
for ^$h -> $r { |
for ^$h -> $r { |
||
for ^$h -> $c { |
for ^$h -> $c { |
||
@sq[$r + $h;$c] = @sq[$r;$c] + $h² * 3; |
@sq[$r + $h; $c] = @sq[$r;$c] + $h² * 3; |
||
@sq[$r;$c + $h] = @sq[$r;$c] + $h² * 2; |
@sq[$r; $c + $h] = @sq[$r;$c] + $h² * 2; |
||
@sq[$r + $h;$c + $h] = @sq[$r;$c] + $h²; |
@sq[$r + $h; $c + $h] = @sq[$r;$c] + $h²; |
||
} |
} |
||
for ^ |
for ^$q -> $c { |
||
next if $c == 0 and $r == ($h-1) div 2; |
next if $c == 0 and $r == ($h-1) div 2; |
||
(@sq[$r |
(@sq[$r;$c], @sq[$r + $h;$c]) = (@sq[$r + $h;$c], @sq[$r;$c]); |
||
} |
} |
||
if $h > 4 { |
|||
for ($n - $q + 1) ..^ $n -> $c { |
|||
(@sq[ |
(@sq[$r;$c], @sq[$r + $h;$c]) = (@sq[$r + $h;$c], @sq[$r;$c]); |
||
⚫ | |||
for ^$h -> $r { |
|||
for ($n - ($h-3) / 2) ..^ $n -> $c { |
|||
(@sq[$r][$c], @sq[$r + $h][$c]) = |
|||
(@sq[$r + $h][$c], @sq[$r][$c]); |
|||
} |
} |
||
} |
} |
||
} |
} |
||
⚫ | |||
} |
} |
||
}</ |
}</syntaxhighlight> |
Latest revision as of 21:58, 28 August 2022
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.
See:
- Magic squares of odd order#Raku
- Magic squares of singly even order#Raku
- Magic squares of doubly even order#Raku
sub MAIN (Int $n where {$n > 0}) {
my @sq;
my $i = 1;
my $h = $n div 2;
my $q = $n div 4;
gen-sq($n);
say .fmt("%{$i.chars}d", ' ') for @sq;
say "\nThe magic number is ", [+] @sq[0].list;
multi sub gen-sq (2) { # invalid
note "Sorry, can not generate a 2 x 2 magic square." and exit;
}
multi sub gen-sq ($n where {$n % 2}) { # odd
my $x = $n/2;
my $y = 0;
@sq[($i % $n ?? $y-- !! $y++) % $n][($i % $n ?? $x++ !! $x) % $n] = $i++ for ^$n²;
}
multi sub gen-sq ($n where {$n %% 4}) { # doubly even
my $x = 0;
my $y = 0;
@sq[$i % $n ?? $y !! $y++][($i-1) % $n] = $i++ for ^$n²;
for ^$q -> $r {
for $q ..^ $n - $q -> $c {
my $ŕ = $n - 1 - $r;
my $ć = $n - 1 - $c;
(@sq[$r;$c], @sq[$ŕ;$ć]) = (@sq[$ŕ;$ć], @sq[$r;$c]);
(@sq[$c;$r], @sq[$ć;$ŕ]) = (@sq[$ć;$ŕ], @sq[$c;$r]);
}
}
}
multi sub gen-sq ($n where {$n %% 2 and $n % 4}) { # singly even
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 ^$q -> $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]);
}
if $h > 4 {
for ($n - $q + 1) ..^ $n -> $c {
(@sq[$r;$c], @sq[$r + $h;$c]) = (@sq[$r + $h;$c], @sq[$r;$c]);
}
}
}
(@sq[$q;$q], @sq[$q+$h;$q]) = (@sq[$q+$h;$q], @sq[$q;$q]);
}
}