例の話題の試験の解答

とりあえず、ざっくりとこんな感じか。

#!/usr/bin/perl

use strict;
use warnings;

my @map;
my @start;
my @goal;
my $i = 0;
while (<>) {
    chomp;
    my @map_line = split(//, $_);
    my $j = 0;
    foreach (@map_line) {
        @start = ($i, $j) if $_ eq 'S';
        @goal  = ($i, $j) if $_ eq 'G';
        $j++;
    }
    push @map, \@map_line;
    $i++;
}
$map[$start[0]][$start[1]] = ' ';
$map[$goal[0]][$goal[1]] = ' ';

my @queue;

my ($x, $y) = @start;
$map[$x][$y] = 0;
until ($x == $goal[0] and $y == $goal[1]) {
    my $last = 0;
    foreach ([$x-1, $y], [$x+1, $y], [$x, $y-1], [$x, $y+1]) {
        my ($nx, $ny) = @$_;
        if ($map[$nx][$ny] eq ' ') {
            $map[$nx][$ny] = $map[$x][$y] + 1;
            push @queue, $_;
        }
    }

    ($x, $y) = @{shift @queue};
}

($x, $y) = @goal;
until ($x == $start[0] and $y == $start[1]) {
    $map[$x][$y] = '$';
    my $last = 0;
    my ($minx, $miny);
    my $min;
    foreach ([$x-1, $y], [$x+1, $y], [$x, $y-1], [$x, $y+1]) {
        my ($nx, $ny) = @$_;
        if ($map[$nx][$ny] !~ /[\$\* ]/ and (not defined $min or $min > $map[$nx][$ny])) {
            $min = $map[$nx][$ny];
            ($minx, $miny) = @$_;
        }
    }
    ($x, $y) = ($minx, $miny);
}

$map[$start[0]][$start[1]] = 'S';
$map[$goal[0]][$goal[1]] = 'G';
foreach (@map) {
    print join('', map { $_ =~ /[\*\$SG]/ ? $_ : ' ' } @$_) . "\n";
}

結果

mkataigi:~$ cat sample
**************************
*S* *                    *
* * *  *  *************  *
* *   *    ************  *
*    *                   *
************** ***********
*                        *
** ***********************
*      *              G  *
*  *      *********** *  *
*    *        ******* *  *
*       *                *
**************************
mkataigi:~$ ./route.pl < sample
**************************
*S* * $$$$               *
*$* *$$* $*************  *
*$* $$*  $$************  *
*$$$$*    $$$$$          *
**************$***********
* $$$$$$$$$$$$$          *
**$***********************
* $$$$$* $$$$$$$$$$$$$G  *
*  *  $$$$*********** *  *
*    *        ******* *  *
*       *                *
**************************

基本的なダイクストラで実装。

他のことやりながらでしたが、だいたい1時間半位だったかな。