Perl, 166 160 characters
Perl, 251 248 246 222 214 208 203 201 193 190 180 176 173 170 166 –> 160 chars.
Solution had 166 strokes when this contest ended, but A. Rex has found a couple ways to shave off 6 more characters:
s!.!$t{$s++}=$&!ge,$s=$r+=99for<>;%d='>.^1<2v3'=~/./g;($r)=grep$d|=$d{$t{$_}},%t;
{$_=$t{$r+=(1,-99,-1,99)[$d^=3*/\\/+m</>]};/[\/\\ ]/&&redo}die/x/?true:false,$/
The first line loads the input into %t
, a table of the board where $t{99*i+j}
holds the character at row i,column j. Then,
%d=split//,'>.^1<2v3' ; ($r)=grep{$d|=$d{$t{$_}}}%t
it searches the elements of %t
for a character that matches > ^ <
or v
, and simultaneously sets $d
to a value between 0 and 3 that indicates the initial direction of the laser beam.
At the beginning of each iteration in the main loop, we update $d
if the beam is currently on a mirror. XOR’ing by 3 gives the correct behavior for a \
mirror and XOR’ing by 1 gives the correct behavior for a /
mirror.
$d^=3*/\\/+m</>
Next, the current position $r
is updated accoring to the current direction.
$r+=(1,-99,-1,99)[$d] ; $_ = $t{$r}
We assign the character at the current position to $_
to make convenient use of the match operators.
/[\/\\ ]/ && redo
Continue if we are on a blank space or a mirror character. Otherwise we terminate true
if we are on the target ($_ =~ /x/
) and false
otherwise.
Limitation: may not work on problems with more than 99 columns. This limitation could be removed at the expense of 3 more characters,