11 push @map, [ split // ];
13 while ($line =~ /\d/g) {
14 my $x = pos($line) - 1;
16 $ducts[$&] = [ $x, $y ];
17 $duct_pos{$x,$y} = $&;
18 say "$& at ", pos($line)-1, ",$#map";
22 my $xmax = $#{ $map[0] };
31 my ($x, $y) = @{ $ducts[$duct] };
32 my @q = ([ $x, $y, 0 ]);
33 my %seen = ("$x,$y" => 1);
37 my ($x, $y, $dist) = @$entry;
38 if ($map[$y][$x] =~ /\d/) {
39 $dist{$duct}{$&} = $dist;
40 say "dist $duct -> $& = $dist";
41 return if (++$ducts_seen >= @ducts);
43 for ([0, 1], [0, -1], [1, 0], [-1, 0]) {
44 my $dx = $x + $_->[0];
45 my $dy = $y + $_->[1];
46 next if $dx < 0 || $dx > $xmax || $dy < 0 || $dy > $ymax
47 || $map[$y][$x] eq '#';
48 next if $seen{$dx,$dy}++;
49 push @q, [ $dx, $dy, $dist+1];
59 my ($dist, $now, @rest) = @_;
61 $dist += $dist{$now}{0};
62 $min_dist = $dist if !defined $min_dist || $dist < $min_dist;
64 for my $i (0 .. $#rest) {
66 my $duct = splice @nr, $i, 1;
67 perm($dist + $dist{$now}{$duct}, $duct, @nr);