4 use experimental 'multidimensional';
8 my @map = map { chomp; y/<>^v/..../; [ split // ] } <>;
9 my $xmax = $#{ $map[0] };
12 my @dx = (1, 0, -1, 0);
13 my @dy = (0, 1, 0, -1);
15 my @crossings = ([1, 0], [$xmax-1, $ymax]);
17 for my $y (1 .. $ymax-1) {
18 for my $x (1 .. $xmax-1) {
19 next if $map[$y][$x] ne '.';
22 my $nx = $x + $dx[$d];
23 my $ny = $y + $dy[$d];
24 $cnt++ if $map[$ny][$nx] eq '.';
27 say "cross ", scalar @crossings, " at $x,$y: $cnt";
28 push @crossings, [$x,$y];
33 for (0 .. $#crossings) {
34 $is_cross{$crossings[$_]->[0],$crossings[$_]->[1]} = $_;
40 my @q = [ 1, 1, 0, 0, 0 ];
42 my ($x, $y, $len, $prevx, $prevdist) = @{ shift @q };
44 if (defined $is_cross{$x,$y}) {
45 my $self = $is_cross{$x,$y};
47 if ($self != $prevx) {
48 my $l = $len - $prevdist;
49 say "$prevx-$self $l";
50 $xnei{$self}{$prevx} = $l;
51 $xnei{$prevx}{$self} = $l;
57 next if $seen{$x,$y,$prevx}++;
60 my $nx = $x + $dx[$d];
61 my $ny = $y + $dy[$d];
64 next if $map[$ny][$nx] eq '#';
65 push @q, [$nx, $ny, $len+1, $prevx, $prevdist];
72 my ($self, $dist) = @_;
74 # say "at $self $dist @path";
76 if ($maxlen < $dist) {
82 for my $nxt (keys %{ $xnei{$self} }) {
84 walk($nxt, $dist + $xnei{$self}{$nxt});