Grokbase Groups Perl golf July 2004
FAQ
Here is a solution to the Rush Hour quiz using the Games::LMSolve module. It
isn't golfized or anything, and was not too optimized - I just wanted to see
if I can solve it using it.

Regards,

Shlomi Fish

<<<
#!/usr/bin/perl -w
package RushHour;

use strict;

use base 'Games::LMSolve::Base';

sub input_board
{
my $self = shift;
my $packed = join("",<STDIN>);
chomp($packed);
return $self->unpack_state($packed);
}

sub pack_state
{
my $self = shift;
my $unpacked = shift;
return join("\n", map { join("", @$_) } @$unpacked);
}

sub unpack_state
{
my $self = shift;
my $packed = shift;
my @lines = split(/\n/,$packed);
chomp(@lines);
return [map { [ split(//, $_) ] } @lines];
}

sub display_state
{
my $self = shift;
my $packed = shift;
return $packed;
}

sub check_if_final_state
{
my $self = shift;
my $state = shift;
foreach my $l (@$state)
{
if ($l->[-1] =~ /^[a-zA-Z]$/)
{
return 1;
}
}
return 0;
}

sub enumerate_moves
{
my $self = shift;
my $state = shift;
my @moves;
my %encountered_cars = ();

my ($x,$y);
for($y=0;$y<@$state;$y++)
{
my $line = $state->[$y];
for($x=0;$x<@$line;$x++)
{
my $char = $line->[$x];
if (exists($encountered_cars{$char}))
{
next;
}
$encountered_cars{$char} = 1;
if ($char =~ /^[a-z]$/)
{
my $x_delta = 1;
while (($x-$x_delta >= 0) && $line->[$x-$x_delta] eq " ")
{
push @moves, +{ 'c' => $char, 'i' => (-$x_delta)};
$x_delta++;
}
$x_delta = 1;
my $x_end = 1;
while ($line->[$x+$x_end] eq $char)
{
$x_end++;
}
$x_end--;
$x_delta = 1;
while (($x+$x_end+$x_delta < @$line) &&
($line->[$x+$x_end+$x_delta] eq " "))
{
push @moves, +{ 'c' => $char, 'i' => $x_delta};
$x_delta++;
}
}
elsif ($char =~ /^[A-Z]$/)
{
my $y_delta = 1;
while (($y-$y_delta >= 0) && $state->[$y-$y_delta]->[$x] eq "
")
{
push @moves, +{ 'c' => $char, 'i' => (-$y_delta)};
$y_delta++;
}
$y_delta = 1;
my $y_end = 1;
while ($state->[$y+$y_end]->[$x] eq $char)
{
$y_end++;
}
$y_end--;
$y_delta = 1;
while (($y+$y_end+$y_delta < @$state) &&
($state->[$y+$y_end+$y_delta]->[$x] eq " "))
{
push @moves, +{ 'c' => $char, 'i' => $y_delta};
$y_delta++;
}
}
}
}
return (@moves);
}

sub perform_move
{
my $self = shift;
my $state = shift;
my $move = shift;
my $state_copy = $self->unpack_state($self->pack_state($state));
my $c = $move->{c};
my $increment = $move->{i};
my ($len);
my ($x, $y);
my $horiz = (($c =~ /^[a-z]$/) ? 1 : 0);
Y_LOOP: for($y=0;$y<@$state_copy;$y++)
{
my $line = $state_copy->[$y];
for($x=0;$x<@$line;$x++)
{
if ($line->[$x] eq $c)
{
if ($horiz)
{
for($len=0;;$len++)
{
if ($line->[$x+$len] ne $c)
{
last;
}
}
my $x_iter;
for($x_iter = 0;$x_iter<$len;$x_iter++)
{
$line->[$x+$x_iter] = " ";
}
for($x_iter = 0;$x_iter<$len;$x_iter++)
{
$line->[$x+$x_iter+$increment] = $c;
}
}
else
{
for($len=0;;$len++)
{
if ($state_copy->[$y+$len]->[$x] ne $c)
{
last;
}
}
my $y_iter;
for($y_iter = 0;$y_iter<$len;$y_iter++)
{
$state_copy->[$y+$y_iter]->[$x] = " ";
}
for($y_iter = 0;$y_iter<$len;$y_iter++)
{
$state_copy->[$y+$y_iter+$increment]->[$x] = $c;
}
}
last Y_LOOP;
}
}
}
return $state_copy;
}

package main;
use strict;

my $self = RushHour->new();
my ($verdict, $final_state) = $self->solve_board("-");
if ($verdict eq "unsolved")
{
exit;
}
my $key = $final_state;
my $state_collection = $self->{'state_collection'};
my $s = $state_collection->{$key};
my @moves = ();
my @states = ($key);

while ($s->{'p'})
{
push @moves, $s->{'m'}->{c} . " " . $s->{m}->{i};
$key = $s->{'p'};
$s = $state_collection->{$key};
push @states, $key;
}
@moves = reverse(@moves);
print map { "$_\n" } @moves;
>>>
--

---------------------------------------------------------------------
Shlomi Fish shlomif@iglu.org.il
Homepage: http://shlomif.il.eu.org/

Knuth is not God! It took him two days to build the Roman Empire.

Search Discussions

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 1 of 1 | next ›
Discussion Overview
groupgolf @
categoriesperl
postedJul 24, '04 at 1:53p
activeJul 24, '04 at 1:53p
posts1
users1
websiteperlgolf.sourceforge.net

1 user in discussion

Shlomi Fish: 1 post

People

Translate

site design / logo © 2021 Grokbase