]> www.fi.muni.cz Git - aoc.git/commitdiff
Day 12: code too long master
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 12 Dec 2024 05:44:51 +0000 (06:44 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 12 Dec 2024 05:44:51 +0000 (06:44 +0100)
2024/23.pl [new file with mode: 0755]
2024/24.pl [new file with mode: 0755]

diff --git a/2024/23.pl b/2024/23.pl
new file mode 100755 (executable)
index 0000000..a5f0aa4
--- /dev/null
@@ -0,0 +1,50 @@
+#!/usr/bin/perl -w
+
+use v5.40;
+
+my @map = map { chomp; [ split // ] } <>;
+my $xmax = $#{ $map[0] };
+my $ymax = $#map;
+
+my %seen;
+my $sum;
+for my $y (0 .. $ymax) {
+       for my $x (0 .. $xmax) {
+               $sum += walk($x, $y) if !$seen{"$x,$y"};
+       }
+}
+say $sum;
+
+sub walk {
+       my ($x0, $y0) = (@_);
+
+       my $m = $map[$y0][$x0];
+       my ($area, $price);
+
+       my @q = [$x0, $y0];
+       while (my $qe = shift @q) {
+               my ($x, $y) = @$qe;
+               next if $seen{"$x,$y"}++;
+
+               $area++;
+
+               for my ($dx, $dy) (
+                       -1, 0,
+                       1, 0,
+                       0, -1,
+                       0, 1,
+               ) {
+                       my ($nx, $ny) = ($x+$dx, $y+$dy);
+                       if ($nx < 0 || $nx > $xmax
+                               || $ny < 0 || $ny > $ymax) {
+                               $price++;
+                       } elsif ($map[$ny][$nx] ne $m) {
+                               $price++;
+                       } else {
+                               push @q, [$nx, $ny];
+                       }
+               }
+       }
+       # say "$m at $_[0] $_[1] area $area price $price";
+       return $area * $price;
+}
diff --git a/2024/24.pl b/2024/24.pl
new file mode 100755 (executable)
index 0000000..a02b392
--- /dev/null
@@ -0,0 +1,82 @@
+#!/usr/bin/perl -w
+
+use v5.40;
+
+my @map = map { chomp; [ split // ] } <>;
+my $xmax = $#{ $map[0] };
+my $ymax = $#map;
+
+my %seen;
+my $sum;
+for my $y (0 .. $ymax) {
+       for my $x (0 .. $xmax) {
+               $sum += walk($x, $y) if !$seen{"$x,$y"};
+       }
+}
+say $sum;
+
+sub walk {
+       my ($x0, $y0) = (@_);
+
+       my $m = $map[$y0][$x0];
+       my ($area, $price);
+
+       my (%sides, @sides);
+       my @q = [$x0, $y0];
+       while (my $qe = shift @q) {
+               my ($x, $y) = @$qe;
+               next if $seen{"$x,$y"}++;
+
+               $area++;
+
+               for my ($dx, $dy, $dir) (
+                       -1, 0, 'L',
+                       1, 0,  'R',
+                       0, -1, 'U',
+                       0, 1,  'D',
+               ) {
+                       my ($nx, $ny) = ($x+$dx, $y+$dy);
+                       if ($nx < 0 || $nx > $xmax
+                               || $ny < 0 || $ny > $ymax
+                               || $map[$ny][$nx] ne $m) {
+                               $sides{"$nx,$ny,$dir"}++;
+                               push @sides, [$nx, $ny, $dir];
+                       } else {
+                               push @q, [$nx, $ny];
+                       }
+               }
+       }
+
+       my %sseen;
+       for my $side (@sides) {
+               my ($x, $y, $dir) = @$side;
+               next if $sseen{"$x,$y,$dir"}++;
+
+               if ($dir =~ /[UD]/) {
+                       my $x1 = $x;
+                       while ($sides{"$x1,$y,$dir"}) {
+                               $sseen{"$x1,$y,$dir"}++;
+                               $x1++;
+                       }
+                       $x1 = $x-1;
+                       while ($sides{"$x1,$y,$dir"}) {
+                               $sseen{"$x1,$y,$dir"}++;
+                               $x1--;
+                       }
+               } else {
+                       my $y1 = $y;
+                       while ($sides{"$x,$y1,$dir"}) {
+                               $sseen{"$x,$y1,$dir"}++;
+                               $y1++;
+                       }
+                       $y1 = $y-1;
+                       while ($sides{"$x,$y1,$dir"}) {
+                               $sseen{"$x,$y1,$dir"}++;
+                               $y1--;
+                       }
+               }
+               $price++;
+       }
+               
+       return $area * $price;
+}