From ab08f90e568538823f4c150df9b6641849b78123 Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Sat, 18 Dec 2021 18:18:30 +0100 Subject: [PATCH] Day 18: slightly cleaner solution --- 36.pl | 79 +++++++++++++++++++++++++---------------------------------- 1 file changed, 34 insertions(+), 45 deletions(-) diff --git a/36.pl b/36.pl index 4371f37..3047f40 100755 --- 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; -} - - -- 2.43.5