]> www.fi.muni.cz Git - aoc.git/commitdiff
Day 16: beam reflections
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Sat, 16 Dec 2023 05:31:12 +0000 (06:31 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Sat, 16 Dec 2023 05:31:12 +0000 (06:31 +0100)
2023/31.pl [new file with mode: 0755]
2023/32.pl [new file with mode: 0755]

diff --git a/2023/31.pl b/2023/31.pl
new file mode 100755 (executable)
index 0000000..bf4af15
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/perl -w
+
+use v5.38;
+use experimental 'multidimensional';
+$; = ';';
+
+my @map = map { chomp; [ split // ] } <>;
+my $xmax = $#{ $map[0] };
+my $ymax = $#map;
+
+my @dirs = ([1, 0], [0, 1], [-1, 0], [0, -1]);
+
+my %seen;
+my @q = [-1, 0, 0];
+
+my @slash = (3, 2, 1, 0);
+my @bs    = (1, 0, 3, 2);
+
+while (@q) {
+       my ($x, $y, $dir) = @{ shift @q };
+       my ($dx, $dy) = @{ $dirs[$dir] };
+
+       $x += $dx; $y += $dy;
+       next if $x < 0 || $y < 0 || $x > $xmax || $y > $ymax;
+
+       next if $seen{$x,$y} && ($seen{$x,$y} & (1 << $dir));
+       $seen{$x,$y} |= (1 << $dir);
+
+       my $pt = $map[$y][$x];
+       if ($pt eq '-' && ($dir == 1 || $dir == 3)) {
+               push @q, [$x, $y, 0], [$x, $y, 2];
+       } elsif ($pt eq '|' && ($dir == 0 || $dir == 2)) {
+               push @q, [$x, $y, 1], [$x, $y, 3];
+       } elsif ($pt eq '/') {
+               push @q, [$x, $y, $slash[$dir]];
+       } elsif ($pt eq '\\') {
+               push @q, [$x, $y, $bs[$dir]];
+       } else {
+               push @q, [$x, $y, $dir];
+       }
+}
+
+say scalar keys %seen;
diff --git a/2023/32.pl b/2023/32.pl
new file mode 100755 (executable)
index 0000000..5f0f7ae
--- /dev/null
@@ -0,0 +1,61 @@
+#!/usr/bin/perl -w
+
+use v5.38;
+use experimental 'multidimensional';
+$; = ';';
+
+my @map = map { chomp; [ split // ] } <>;
+my $xmax = $#{ $map[0] };
+my $ymax = $#map;
+
+my @dirs = ([1, 0], [0, 1], [-1, 0], [0, -1]);
+
+my @slash = (3, 2, 1, 0);
+my @bs    = (1, 0, 3, 2);
+
+sub energ ($pt) {
+       my %seen;
+       my @q = $pt;
+       while (@q) {
+               my ($x, $y, $dir) = @{ shift @q };
+               my ($dx, $dy) = @{ $dirs[$dir] };
+
+               $x += $dx; $y += $dy;
+               next if $x < 0 || $y < 0 || $x > $xmax || $y > $ymax;
+
+               next if $seen{$x,$y} && $seen{$x,$y} & (1 << $dir);
+               $seen{$x,$y} |= (1 << $dir);
+
+               my $pt = $map[$y][$x];
+               if ($pt eq '-' && ($dir == 1 || $dir == 3)) {
+                       push @q, [$x, $y, 0], [$x, $y, 2];
+               } elsif ($pt eq '|' && ($dir == 0 || $dir == 2)) {
+                       push @q, [$x, $y, 1], [$x, $y, 3];
+               } elsif ($pt eq '/') {
+                       push @q, [$x, $y, $slash[$dir]];
+               } elsif ($pt eq '\\') {
+                       push @q, [$x, $y, $bs[$dir]];
+               } else {
+                       push @q, [$x, $y, $dir];
+               }
+       }
+       return scalar keys %seen;
+}
+
+my $max = 0;
+
+for (0 .. $xmax) {
+       my $cnt = energ([$_, -1, 1]);
+       $max = $cnt if $cnt > $max;
+       $cnt = energ([$_, $ymax+1, 3]);
+       $max = $cnt if $cnt > $max;
+}
+
+for (0 .. $ymax) {
+       my $cnt = energ([-1, $_, 0]);
+       $max = $cnt if $cnt > $max;
+       $cnt = energ([$xmax+1, $_, 2]);
+       $max = $cnt if $cnt > $max;
+}
+
+say $max;