Peaceful chess queen armies: Difference between revisions
Content added Content deleted
SqrtNegInf (talk | contribs) (→{{header|Perl}}: Added refactored version of code) |
|||
Line 1,730: | Line 1,730: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
===Terse=== |
|||
<lang perl> |
<lang perl>use strict; |
||
use strict; # http://www.rosettacode.org/wiki/Peaceful_chess_queen_armies |
|||
use warnings; |
use warnings; |
||
Line 1,738: | Line 1,737: | ||
my $n = shift // 5; |
my $n = shift // 5; |
||
my %seen; |
my %seen; |
||
my $gaps = join '|', qr/-*/, map qr/.{$_}(?:-.{$_})*/ |
my $gaps = join '|', qr/-*/, map qr/.{$_}(?:-.{$_})*/s, $n-1, $n, $n+1; |
||
my $attack = qr/(\w)(?:$gaps)(?!\1)\w/; |
my $attack = qr/(\w)(?:$gaps)(?!\1)\w/; |
||
place( scalar |
place( scalar ('-' x $n . "\n") x $n ); |
||
print "No solution to $m $n\n"; |
print "No solution to $m $n\n"; |
||
Line 1,752: | Line 1,751: | ||
}</lang> |
}</lang> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre>Solution to 4 5 |
||
⚫ | |||
W---W |
W---W |
||
Line 1,759: | Line 1,757: | ||
-B-B- |
-B-B- |
||
--B-- |
--B-- |
||
W---W |
W---W</pre> |
||
===Verbose=== |
|||
A refactored version of the same code, with fancier output. Does not scale well for larger boards. |
|||
<lang perl>use strict; |
|||
use warnings; |
|||
use feature 'say'; |
|||
use feature 'state'; |
|||
use utf8; |
|||
binmode(STDOUT, ':utf8'); |
|||
my $solution; # algorithm requires this variable to be global |
|||
# recursively place the next queen |
|||
sub place { |
|||
my($board, $n, $m, $empty_square) = @_; |
|||
state %seen; |
|||
# logic of 'attack' regex: queen ( ... paths between queens containing only empty squares ... ) queen of other color |
|||
my $attack = |
|||
'([WB])' . # 1st queen |
|||
'(?:' . |
|||
join('|', |
|||
"[$empty_square]*", |
|||
map { |
|||
"(?^s:.{$_}(?:[$empty_square].{$_})*)" |
|||
} $n-1, $n, $n+1 |
|||
) . |
|||
')' . |
|||
'(?!\1)[WB]'; # 2nd queen |
|||
# bail out if seen this configuration previously, or attack detected |
|||
return if $seen{$board}++ or $board =~ /$attack/; |
|||
# success if queen count is m×2 |
|||
$solution = $board and return if $m * 2 == (my $have = $board =~ tr/WB//); |
|||
# place the next queen (alternating colors each time) |
|||
place( $board =~ s/[$empty_square]\G/ qw<W B>[$have % 2] /er, $n, $m, $empty_square ) |
|||
while $board =~ /[$empty_square]/g; |
|||
} |
|||
my($m, $n) = (shift, shift) || (4, 5); |
|||
my $empty_square = '◦•'; |
|||
my $board = join "\n", map { substr $empty_square x $n, $_%2, $n } 1..$n; |
|||
place( $board, $n, $m, $empty_square ); |
|||
say $solution |
|||
? sprintf "Solution to $m $n\n\n%s", map { s/(.)/$1 /gm; s/B /♛/gm; s/W /♕/gmr } $solution |
|||
: "No solution to $m $n";</lang> |
|||
{{out}} |
|||
⚫ | |||
• ♛• ♛• |
|||
♛• ◦ • ◦ |
|||
• ◦ ♕◦ ♕ |
|||
♛• ◦ • ◦ |
|||
• ◦ ♕◦ ♕ |
|||
</pre> |
</pre> |
||