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;
-}
-
-