my v1:
2 3 4 8
1 6 0 7
5 10 11 12
9 13 14 15
2 3 4 8
1 6 7 0
5 10 11 12
9 13 14 15
2 3 4 0
1 6 7 8
5 10 11 12
9 13 14 15
2 3 0 4
1 6 7 8
5 10 11 12
9 13 14 15
2 0 3 4
1 6 7 8
5 10 11 12
9 13 14 15
0 2 3 4
1 6 7 8
5 10 11 12
9 13 14 15
1 2 3 4
0 6 7 8
5 10 11 12
9 13 14 15
1 2 3 4
5 6 7 8
0 10 11 12
9 13 14 15
1 2 3 4
5 6 7 8
9 10 11 12
0 13 14 15
1 2 3 4
5 6 7 8
9 10 11 12
13 0 14 15
1 2 3 4
5 6 7 8
9 10 11 12
13 14 0 15
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 0
E N W W W S S S E E E
#!/usr/bin/perl
# This is perl 5, version 28
# subversion 2 (v5.28.2)
# built for arm-android
# __________ USE __________
use 5.010;
# __________ RUN __________
my $SHOW = 1;
my @puzzle15 = map [split], <DATA>;
solve( \@puzzle15 );
# __________ SUB __________
sub finish {
my $f;
vec( $f, $_, 4 ) = $_ + 1 for 0 .. 14;
vec( $f, 15, 4 ) = 0;
return $f;
}
sub puzzle2map {
my $p = shift;
my $map;
my $k = 0;
for my $i ( 0 .. 3 ) {
vec( $map, $k++, 4 ) = $p->[$i][$_] for 0 .. 3;
}
return $map;
}
sub move {
# CODE ME!!
[ 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 3 ],
[ 0, 2, 3 ], [ 0, 1, 2, 3 ], [ 0, 1, 2, 3 ], [ 0, 1, 3 ],
[ 0, 2, 3 ], [ 0, 1, 2, 3 ], [ 0, 1, 2, 3 ], [ 0, 1, 3 ],
[ 0, 2 ], [ 0, 1, 2 ], [ 0, 1, 2 ], [ 0, 1 ];
}
sub init {
my $map = shift;
my ($indes) = grep !vec( $map, $_, 4 ), 0 .. 15;
return [ $map, $indes, '' ];
}
sub gimme {
my ( $map, $pos, $dir ) = @_;
state $jump = [ -4, -1, 1, 4 ];
my $next = $pos + $jump->[$dir];
vec( $map, $pos, 4 ) = vec( $map, $next, 4 );
vec( $map, $next, 4 ) = 0;
return $map, $next;
}
sub show {
my ( $map, $dir ) = @_;
my @dir = split //, $dir;
push @dir, 0;
my ($pos) = grep !vec( $map, $_, 4 ), 0 .. 15;
for my $d (@dir) {
for my $i ( 0 .. 3 ) {
my $indes = $i * 4;
my @line =
map { sprintf "%3s", vec( $map, $_, 4 ) } $indes .. $indes + 3;
say @line;
}
say '';
( $map, $pos ) = gimme( $map, $pos, $d );
}
}
sub solve {
my $puz = shift;
my $finish = finish();
my $map = puzzle2map($puz);
my @move = move();
my @next = init($map);
my %has;
while (@next) {
my $test = shift @next;
my ( $try, $pos, $dir ) = @$test;
if ( $try eq $finish ) {
show( $map, $dir ) if $SHOW;
$dir =~ tr/0123/NWES/;
say join ' ', split //, $dir;
exit;
}
for my $d ( @{ $move[$pos] } ) {
my ( $try, $pos ) = gimme( $try, $pos, $d );
push @next, [ $try, $pos, $dir . $d ] if !$has{$try}++;
}
}
say "no solution";
}
__DATA__
2 3 4 8
1 6 0 7
5 10 11 12
9 13 14 15