Script to find all the Magic Squares for the numbers 3-11
and the sum 21
.
my $boxes = (3..11).permutations;
my $magic = 21;
for $boxes.grep(&magic-square) -> @box {
for @box.rotor(3) -> @row {
say @row.fmt('%2d');
}
print "\n";
}
sub magic-square( \nums ) {
$magic == nums[0] + nums[1] + nums[2]
&& $magic == nums[3] + nums[4] + nums[5]
&& $magic == nums[6] + nums[7] + nums[8]
&& $magic == nums[0] + nums[3] + nums[6]
&& $magic == nums[1] + nums[4] + nums[7]
&& $magic == nums[2] + nums[5] + nums[8]
&& $magic == nums[0] + nums[4] + nums[8]
&& $magic == nums[6] + nums[4] + nums[2]
}
say "Completed in {now - INIT now} seconds"
There are 8 Magic Squares in total.
Of course, they are all just mirrored/flipped versions of the first one, so we can cheat a little.
my $boxes = (3..11).permutations;
my $magic = 21;
# get the first permutation that satisfies magic-square()
with $boxes.first(&magic-square).rotor(3) -> @box {
# transpose (zip), reverse, and mirror the rows to create the other permutations
# original
box-print( @box );
# transposed
box-print( [Z] @box );
# reversed original
box-print( @box.reverse );
# reversed transposed
box-print( [Z] @box.reverse );
# original, mirrored
box-print( @box.map: *.reverse );
# transposed, mirrored
box-print( [Z] @box.map: *.reverse );
# reversed original, mirrored
box-print( @box.reverse.map: *.reverse );
# reversed transposed, mirrored
box-print( [Z] @box.reverse.map: *.reverse );
}
sub box-print( @box ) {
for @box -> @row {
say @row.fmt('%2d');
}
print "\n";
}
sub magic-square( \nums ) {
$magic == nums[0] + nums[1] + nums[2]
&& $magic == nums[3] + nums[4] + nums[5]
&& $magic == nums[6] + nums[7] + nums[8]
&& $magic == nums[0] + nums[3] + nums[6]
&& $magic == nums[1] + nums[4] + nums[7]
&& $magic == nums[2] + nums[5] + nums[8]
&& $magic == nums[0] + nums[4] + nums[8]
&& $magic == nums[6] + nums[4] + nums[2]
}
say "Completed in {now - INIT now} seconds"