5 my @map = map { chomp; [ split // ] } <>;
6 my $maxx = @{ $map[0] };
14 my ($name, $x, $y) = @_;
15 say "add_portal: $name, $x, $y";
16 if (defined $portals{$name}) {
17 my ($x1, $y1) = @{ $portals{$name} };
18 $map[$y][$x] = [$x1, $y1];
19 $map[$y1][$x1] = [$x, $y];
20 say "portal $name: $x,$y <==> $x1,$y1";
22 $portals{$name} = [$x, $y];
28 for my $x (2 .. $maxx-3) {
29 for my $y (2 .. $maxy-3) {
30 next if $map[$y][$x] ne '.';
31 my $l1 = $map[$y+$d[1]][$x+$d[0]];
32 my $l2 = $map[$y+$d[3]][$x+$d[2]];
33 next if "$l1$l2" !~ /^[A-Z][A-Z]$/;
34 add_portal("$l1$l2", $x, $y);
39 find_portals(0, -2, 0, -1);
40 find_portals(0, 1, 0, 2);
41 find_portals(-2, 0, -1, 0);
42 find_portals(1, 0, 2, 0);
46 my @q = [ @{ $portals{'AA'} }, 0 ];
47 my ($ex, $ey) = @{ $portals{'ZZ'} };
48 say "walking towards $ex, $ey";
51 my ($x, $y, $steps) = @{ shift @q };
52 next if $seen{$x,$y}++;
53 say "at $x,$y $steps";
55 if ($x == $ex && $y == $ey) {
56 say "Found after $steps steps";
61 if (ref $map[$y][$x]) {
62 my ($nx, $ny) = @{ $map[$y][$x] };
63 push @q, [ $nx, $ny, $steps ];
65 for my ($dx, $dy) (0, 1, 1, 0, -1, 0, 0, -1) {
68 next if $map[$ny][$nx] ne '.' && !ref $map[$ny][$nx];
69 push @q, [$nx, $ny, $steps];