enum Direction <up left right down>;
my %Conns =
'-' => [left, right],
'|' => [up, down],
'L' => [up, right],
'J' => [up, left],
'F' => [right, down],
'7' => [left, down],
'.' => [],
;
my @M = $*IN.lines.map(*.comb.Array);
my $row = @M.first(/S/, :k);
my $col = @M[$row].first(/S/, :k);
my %vertical-walls is SetHash;
my $dir = do
if $row > 0 && %Conns{@M[$row-1;$col]}.grep(down) {
%vertical-walls.set("{$row-1}:{$col}");
up
} elsif $row < +@M - 1 && %Conns{@M[$row+1;$col]}.grep(up) {
%vertical-walls.set("{$row}:{$col}");
%vertical-walls.set("{$row+1}:{$col}");
down
} elsif $col > 0 && %Conns{@M[$row;$col-1]}.grep(right) {
left
} elsif $col < +@M[0] - 1 && %Conns{@M[$row;$col-1]}.grep(left) {
right
};
my $steps = 1;
while @M[$row;$col] ne 'S' || $steps == 1 {
@M[$row;$col] .= trans('-|F7LJ' => '─│┌┐└┘');
given $dir {
when up { --$row; %vertical-walls.set("{$row}:{$col}"); }
when down { ++$row; %vertical-walls.set("{$row}:{$col}"); }
when left { --$col; }
when right { ++$col; }
}
last if @M[$row;$col] eq 'S';
my $new-dir = (%Conns{@M[$row;$col]} (-) Direction(3 - $dir)).keys.first;
%vertical-walls.set( "{$row}:{$col}") if $new-dir == down && $dir == (left, right).any;
%vertical-walls.unset("{$row}:{$col}") if $dir == down && $new-dir == (left, right).any;
$dir = $new-dir;
++$steps;
}
put 'part 1: ', $steps / 2;
put 'part 2: ', +(^+@M X ^+@M[0]).grep(->(\R,\C) {
@M[R;C].match(/<[-|.F7LJ]>/) &&
%vertical-walls{ (^C).map({ "{R}:{$_}" }) }.grep(?*).elems % 2
});