From: Jan "Yenya" Kasprzak Date: Sun, 10 Dec 2023 15:28:10 +0000 (+0100) Subject: Day 10: polished solution X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=aoc.git;a=commitdiff_plain;h=effe859821bf2efb6064b8adc70d520dd02bdcb6 Day 10: polished solution --- diff --git a/2023/20.pl b/2023/20.pl index c6d299a..9a359f5 100755 --- a/2023/20.pl +++ b/2023/20.pl @@ -1,101 +1,74 @@ #!/usr/bin/perl -w use v5.38; -use experimental 'multidimensional', 'for_list', 'builtin'; -use builtin 'indexed'; -use List::Util; -use Y::AoC::Task; +use experimental 'multidimensional'; $; = ';'; -# t; -my @map = map { chomp; [ split //, ".$_." ] } <>; -push @map, [ ('.') x @{ $map[0]} ]; -unshift @map, [ ('.') x @{$map[0]} ]; -my $xmax = $#{$map[0]}; -my $ymax = $#map; +my @map; +my ($x, $y); -my ($sx, $sy); -for my $x (0 .. $xmax) { -for my $y (0 .. $ymax) { - next if $map[$y][$x] ne 'S'; - $sx = $x; $sy = $y; -} } +while (<>) { + chomp; + if (/S/g) { + $x = pos; + $y = 1 + @map; + } + push @map, [ split //, ".$_." ]; +} + +push @map, [ ('.') x @{ $map[0] } ]; +unshift @map, [ ('.') x @{ $map[0] } ]; +my $xmax = $#{$map[0]}; +my $ymax = $#map; +# 0=E 1=S 2=W 3=N my %dirs = ( - '|' => [ 0, -1, 0, 1], - '-' => [-1, 0, 1, 0], - 'J' => [-1, 0, 0, -1], - 'L' => [ 1, 0, 0, -1], - 'F' => [ 1, 0, 0, 1], - '7' => [-1, 0, 0, 1], + '|' => '13', + '-' => '02', + 'J' => '23', + 'L' => '03', + 'F' => '01', + '7' => '12', ); +my @dx = (1, 0, -1, 0); +my @dy = (0, 1, 0, -1); - -if ($map[$sy][$sx-1] eq '-' && $map[$sy][$sx+1] eq '-') { - $map[$sy][$sx] = '-'; -} elsif ($map[$sy+1][$sx] eq '|' && $map[$sy-1][$sx] eq '|') { - $map[$sy][$sx] = '|'; -} elsif ($map[$sy][$sx-1] eq '-' && $map[$sy-1][$sx] eq '|') { - $map[$sy][$sx] = 'J'; -} elsif ($map[$sy][$sx-1] eq '-' && $map[$sy+1][$sx] eq '|') { - $map[$sy][$sx] = '7'; -} elsif ($map[$sy][$sx+1] eq '-' && $map[$sy-1][$sx] eq '|') { - $map[$sy][$sx] = 'L'; -} elsif ($map[$sy][$sx+1] eq '-' && $map[$sy+1][$sx] eq '|') { - $map[$sy][$sx] = 'F'; +my $dir; +for my $d (0 .. 3) { + my $revdir = $d ^ 2; + my $p = $map[ $y+$dy[$d] ][ $x+$dx[$d] ]; + $dir .= $d if $dirs{$p} =~ /$revdir/; } -say "starting at $sx, $sy $map[$sy][$sx]"; +my %dir2sym = reverse %dirs; +$map[$y][$x] = $dir2sym{$dir}; # fill in the start point +$dir =~ s/.//; # Take any valid direction + my %seen; -my $len = 0; -my ($px, $py); -while (!$seen{$sx,$sy}++) { - my @d = $dirs{ $map[$sy][$sx] }->@*; - if (!defined($px) || ($px != $d[0] || $py != $d[1])) { - $sx += $d[0]; - $sy += $d[1]; - $px = -$d[0]; - $py = -$d[1]; - } else { - $sx += $d[2]; - $sy += $d[3]; - $px = -$d[2]; - $py = -$d[3]; - } - ++$len; +while (1) { + $x += $dx[$dir]; + $y += $dy[$dir]; + last if $seen{$x,$y}++; + $dir ^= 2; + ($dir) = $dirs{ $map[$y][$x] } =~ /([^$dir])/; } -say "loop len ", $len/2; +say "loop half: ", (keys %seen)/2; my $sum; -for my $x (0 .. $xmax) { +for my $y (0 .. $ymax) { my $in = 0; - my $left = 0; - for my $y (0 .. $ymax) { + for my $x (0 .. $xmax) { if ($seen{$x,$y}) { my $pt = $map[$y][$x]; - if ($pt eq '-') { - $in = !$in; - } elsif ($pt eq '7') { - $left = 1; - } elsif ($pt eq 'F') { - $left = -1; - } elsif ($pt eq 'J') { - if ($left == -1) { - $in = !$in; - } - } elsif ($pt eq 'L') { - if ($left == 1) { - $in = !$in; - } - } - say "$x $y in $in left $left"; - } elsif ($in) { - say "$x $y inside"; + $in += 2 if $pt eq '|'; + $in++ if $pt =~ /[L7]/; + $in-- if $pt =~ /[FJ]/; + } elsif ($in % 4 == 2) { $sum++; } } } -say $sum; +say "inside: ", $sum;