]> www.fi.muni.cz Git - aoc.git/commitdiff
Day 18: slightly cleaner solution
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Sat, 18 Dec 2021 17:18:30 +0000 (18:18 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Sat, 18 Dec 2021 17:18:30 +0000 (18:18 +0100)
36.pl

diff --git a/36.pl b/36.pl
index 4371f379c2365e8bddb58aae75f8885810f8bc84..3047f40127b14a4292728bed59ece933f465d4f5 100755 (executable)
--- a/36.pl
+++ b/36.pl
@@ -2,57 +2,46 @@
 
 use v5.16;
 
-$/ = undef;
-my @nums = split /\n/, <>;
+sub add {
+       $_ = "[$_[0],$_[1]]";
+       my $modified;
+       do {
+               $modified = undef;
+               my ($i, $depth) = (0, 0);
+               while ($i < length) {
+                       $depth-- if substr($_, $i, 1) eq ']';
+                       $depth++ if substr($_, $i, 1) eq '[';
+                       
+                       if ($depth >= 5) {
+                               pos = $i;
+                               next unless s/\G\[(\d+),(\d+)\]/X/;
+                               my ($l, $r) = ($1, $2);
+                               s/(\d+)([^\d]*X)/($1+$l).$2/e;
+                               s/(X[^\d]*)(\d+)/$1.($2+$r)/e;
+                               s/X/0/;
+                               $modified++; $depth--;
+                       }
+                       $i++;
+               }
+               $modified++ if s|\d{2,}|'['.int($&/2).','.int(($&+1)/2).']'|e;
+       } while ($modified);
+       return $_;
+}
+
+sub magnitude { $_ = shift; 1 while s/\[(\d+),(\d+)\]/3*$1+2*$2/e; $_ }
+
+use List::Util qw(reduce);
+
+chomp (my @nums = <>);
+
+say magnitude( reduce { add($a, $b) } @nums );
 
 my $max = 0;
 for my $i (0 .. $#nums) {
 for my $j (0 .. $#nums) {
        next if $i == $j;
-       my $r = add($nums[$i], $nums[$j]);
+       my $r = magnitude( add($nums[$i], $nums[$j]) );
        $max = $r if ($max < $r);
 } }
 
 say $max;
-
-sub add {
-       my ($n1, $n2) = @_;
-       say "\nadd:   $n1\nto:    $n2";
-       my $res = "[$n1,$n2]";
-       ACTION:
-       while (1) {
-               say "have:  $res";
-               # explode
-               my $depth = 0;
-               for my $i (0 .. length($res)-1) {
-                       $depth++ if substr($res, $i, 1) eq '[';
-                       $depth-- if substr($res, $i, 1) eq ']';
-                       
-                       if ($depth >= 5) {
-                               pos($res) = $i;
-                               next if $res !~ /\G\[(\d+),(\d+)\]/;
-                               say "explode at $i";
-                               pos($res) = $i;
-                               $res =~ s/\G\[(\d+),(\d+)\]/X/;
-                               say "X:     $res";
-                               my $l = $1;
-                               my $r = $2;
-                               $res =~ s/(\d+)([^\d]*X)/($1+$l).$2/e;
-                               $res =~ s/(X[^\d]*)(\d+)/"$1".($2+$r)/e;
-                               $res =~ s/X/0/;
-                               say "after: $res";
-                               next ACTION;
-                       }
-               }
-               # split
-               if ($res =~ s|\d{2,}|'['.int($&/2).','.int(($&+1)/2).']'|e) {
-                       say "split: $res";
-                       next ACTION;
-               }
-               last;
-       }
-       1 while $res =~ s/\[(\d+),(\d+)\]/3*$1+2*$2/e;
-       return $res;
-}
-
-