There was an article yesterday in
Shashdot about writing a Python script that solved the
Knight's Tour Problem in
60 lines and less than
1 second for a
100x100 board. PerlMonks have already been encountered with this problem in this
node but the question remained unanswered. So, I spent some time and made a Perl script,
much shorter (35 lines) and
faster (<<1sec) for the same benchmark. If you feel like spending some leisure time over the problem and try to squeeze more the Perl solution, I would be happy to hear some thoughts. Here is my code.
if(@ARGV<4) {print "\nUse: SIZE START_X START_Y [0,1]" and exit;}
our ($N,$X0,$Y0,$VERBOSE) = @ARGV ;
our ($MOVES,@moves,@board)= (0,([-2,-1], [-1,-2], [-2 ,1],[-1 ,2], [2
+,-1], [1, -2],[2, 1],[1, 2]),());
my $last_move = [$X0,$Y0] and inform_board();
$last_move = inform_board($last_move) while($MOVES< $N*$N);
############### SUBROUTINES ########################
sub init { return ($_[0]>$N/2)? init($N-1-$_[0],$_[1]) : ($_[1]>$N/2?
+init($_[0],$N-1-$_[1]):($_[0]>=2 && $_[1]>=2? 8:(($_[0] >=2 && $_[1]=
+=1 || $_[1]>=2 && $_[0]==1)?6:($_[0]+$_[1]>1?4:($_[0]+$_[1]==1?3:2)))
+) )}
sub inRange{
my ($pos, $D) = @_;
my ($x,$y) = ($pos->[0]+$D->[0], $pos->[1]+$D->[1]);
return ($x>=0 && $x<$N && $y >= 0 && $y<$N && $board[$x][$y]>=0)?
+ [$x,$y] : 0;
}
sub inform_board {
my ($moved_to) = @_;
if($moved_to)
{
$MOVES++;
print "\n$MOVES.",$moved_to->[0],",",$moved_to->[1] if $VERBOSE;
my ($MIN,$next_to_move) = (10,[]);
foreach(@moves)
{
if(my $finalPos = inRange($moved_to, $_))
{
my $value_ref = \$board[$finalPos->[0]][$finalPos->[1]];
($MIN,$next_to_move, $board[$moved_to-> [0]][$moved_to->[1]]) =
+($$value_ref,$finalPos,0) if(--$$value_ref>=0 && $$value_ref < $MIN);
+ } }
return $next_to_move;
}
else
{
push @board, [(0)x $N] for(1..$N);
for my $i (0..$N-1) { $board[$i][$_] = init($i,$_) for (0..$N-1);}
} }
Some hints: The
Warnsdorff's algorithm is used for the solution.
init() initializes the board
inRange() Says is a knight move is inside the board limits
inform_board() Marks the last-visited square of the board and returns the next square to move according to the algorithm
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.