]> www.fi.muni.cz Git - aoc.git/commitdiff
Day 10: polished solution
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Sun, 10 Dec 2023 15:28:10 +0000 (16:28 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Sun, 10 Dec 2023 16:04:55 +0000 (17:04 +0100)
2023/20.pl

index c6d299aecd3fe8177ca60591553fb78300f47af6..9a359f5f755050479d55e754c0bded3a853b4fc8 100755 (executable)
 #!/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;