Advertisement
Guest User

Untitled

a guest
Dec 19th, 2021
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 5.76 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. $filename = "18.txt";
  4.  
  5. open(FILE, $filename);
  6. @data = <FILE>;
  7. close(FILE);
  8.  
  9. @datacopy = @data;
  10.  
  11. while ($#data > 0) { #Run code until only 1 line is remaining in input.
  12.  
  13.     $linea = $data[0]; #Take first and second line
  14.     $lineb = $data[1];
  15.     splice(@data, 1, 1);
  16.     $linea =~ s/[^\[\]\,0-9]//sgi;
  17.     $lineb =~ s/[^\[\]\,0-9]//sgi;
  18.     $workset = "[".$linea.",".$lineb."]"; #Add together
  19.  
  20.     $outerchanged = 1;
  21.     while ($outerchanged == 1) { #Run until no more changes at all can be made.
  22.         $outerchanged = 0;
  23.  
  24.         $innerchanged = 1;
  25.         while ($innerchanged == 1) { #Run until no more explosions can be made.
  26.             $innerchanged = 0;
  27.             $newworkset = preexplode($workset);
  28.             if ($newworkset ne $workset) {
  29.                 $innerchanged = 1;
  30.                 $outerchanged = 1;
  31.             }
  32.             $workset = $newworkset;
  33.         }
  34.  
  35.  
  36.         $newworkset = dosplit($workset);
  37.         if ($newworkset ne $workset) {
  38.             $outerchanged = 1;
  39.         }
  40.         $workset = $newworkset;
  41.  
  42.     }
  43.  
  44.     $data[0] = $workset; #Replace first line with reduced set.
  45. }
  46.  
  47. print $workset."\n";
  48. print premagnitude($data[0])."\n";
  49.  
  50.  
  51. $highestwk = 0;
  52. $cv = "";
  53.  
  54. for ($i = 0; $i < $#datacopy + 1; $i++) {
  55.     for ($n = $i + 1; $n < $#datacopy + 1; $n++) { #Try each line against each other in a bruteforce fashion
  56.         $linea = $datacopy[$i];
  57.         $lineb = $datacopy[$n];
  58.         $linea =~ s/[^\[\]\,0-9]//sgi;
  59.         $lineb =~ s/[^\[\]\,0-9]//sgi;
  60.         $workset = "[".$linea.",".$lineb."]";
  61.  
  62.         $outerchanged = 1;
  63.         while ($outerchanged == 1) {
  64.             $outerchanged = 0;
  65.             $innerchanged = 1;
  66.             while ($innerchanged == 1) {
  67.                 $innerchanged = 0;
  68.                 $newworkset = preexplode($workset);
  69.                 if ($newworkset ne $workset) {
  70.                     $innerchanged = 1;
  71.                     $outerchanged = 1;
  72.                 }
  73.                 $workset = $newworkset;
  74.             }
  75.  
  76.             $newworkset = dosplit($workset);
  77.             if ($newworkset ne $workset) {
  78.                 $outerchanged = 1;
  79.             }
  80.             $workset = $newworkset;
  81.         }
  82.  
  83.         $wkc = premagnitude($workset);
  84.  
  85.         if ($wkc > $highestwk) {
  86.             $highestwk = $wkc;
  87.             $cv = $workset;
  88.         }
  89.  
  90.     }
  91. }
  92.  
  93.  
  94. print $cv."\n";
  95. print $highestwk."\n";
  96.  
  97.  
  98.  
  99. sub dosplit() {
  100.     my $zworkset = $_[0];
  101.     my $num;
  102.     my $lower;
  103.     my $higher;
  104.  
  105.     if ($zworkset =~ m/(\d\d+)/) { #Any number with more than 1 digit
  106.         $num = $1 / 2;
  107.         $lower = int($num);
  108.         $higher = int($num + 0.9);
  109.         $zworkset =~ s/\d\d/\[$lower,$higher\]/; #Replace with the pair (split).
  110.     }
  111.  
  112.     return $zworkset;
  113. }
  114.  
  115.  
  116.  
  117. sub premagnitude() {
  118.     my $zworkset = $_[0];
  119.     my $pointer;
  120.     my @chars = ('aa'..'zz','AA'..'ZZ');
  121.     my $result;
  122.  
  123.     %recursive = ();
  124.     for ($pointer = 0; $pointer < $#chars + 1; $pointer++) { #Put each pair in a hash array such as X = Y,Z, where Y/Z can be a real number or point at another hash array entry.
  125.         $zworkset =~ s/\[([A-Za-z0-9]+),([A-Za-z0-9]+)\]/$chars[$pointer]/;
  126.         $recursive{$chars[$pointer]} = $1.",".$2;
  127.         if ($zworkset =~ m/^([A-Za-z0-9]+)$/) {
  128.             last;
  129.         }
  130.     }
  131.  
  132.     $result = magnitude($zworkset);
  133.     return $result;
  134. }
  135.  
  136.  
  137. sub magnitude() {
  138.     my $input = $_[0];
  139.     my $pa;
  140.     my $pb;
  141.  
  142.     my $suma;
  143.     my $sumb;
  144.  
  145.     ($pa, $pb) = split(",",$recursive{$input});
  146.  
  147.     if ($pa =~ m/^\d$/) { #If left part is a number, just put it in $suma.
  148.         $suma = int($pa);
  149.     }
  150.     else
  151.     {
  152.         $suma = magnitude($pa); #If its a pair of letters, then we must dig deeper.
  153.     }
  154.  
  155.     if ($pb =~ m/^\d$/) {
  156.         $sumb = int($pb); #If right part is a number, just put it in $sumb
  157.     }
  158.     else
  159.     {
  160.         $sumb = magnitude($pb); #If its a pair or letters, then we must dig deeper.
  161.     }
  162.     return ($suma * 3) + ($sumb * 2);
  163. }
  164.  
  165. sub preexplode() {
  166.     my $zworkset = $_[0];
  167.     my $pointer;
  168.     my @chars = ('aa'..'zz','AA'..'ZZ');
  169.     my $leftpart;
  170.     my $rightpart;
  171.     my $num;
  172.  
  173.     $leftnum = 0;
  174.     $rightnum = 0;
  175.     $didexplode = 0;
  176.     %recursive = ();
  177.     for ($pointer = 0; $pointer < $#chars + 1; $pointer++) { #Put each pair in a hash array such as X = Y,Z, where Y/Z can be a real number or point at another hash array entry.
  178.         $zworkset =~ s/\[([A-Za-z0-9]+),([A-Za-z0-9]+)\]/$chars[$pointer]/;
  179.         $recursive{$chars[$pointer]} = $1.",".$2;
  180.         if ($zworkset =~ m/^([A-Za-z0-9]+)$/) {
  181.             last;
  182.         }
  183.     }
  184.  
  185.     explode($zworkset, 0); #Run recursive function. This function MODIFIES %recursive directly (thats why I haven't prepended it with "my").
  186.  
  187.     while ($zworkset =~ m/[a-zA-Z]+/) {
  188.         $zworkset =~ s/([a-zA-Z]+)/\[$recursive{$1}\]/g; #Reconstruct snailfish numbers from hash array by using regex to replace pair of letters with their corresponding pairs from hash array.
  189.     }
  190.  
  191.     if ($zworkset =~ m/\[#\]/) { #There is a bomb, explode the bomb!
  192.         ($leftpart, $rightpart) = split("#", $zworkset);
  193.  
  194.         if ($leftpart =~ m/([0-9]+)[^0-9]+[\[]$/) { #If there is any numbers to the left...
  195.             $num = $1;
  196.             $num = $num + $leftnum;
  197.             $leftpart =~ s/([0-9]+)([^0-9]+)[\[]$/$num$2\[/; #Add it.
  198.         }
  199.         if ($rightpart =~ m/^[\]][^0-9]+([0-9]+)/) { #If there is any numbers to the right...
  200.             $num = $1;
  201.             $num = $num + $rightnum;
  202.             $rightpart =~ s/^[\]]([^0-9]+)([0-9]+)/\]$1$num/; #Add it.
  203.         }
  204.         $zworkset = $leftpart."#".$rightpart; #Reconstruct the snailfish number with bomb.
  205.         $zworkset =~ s/\[#\]/0/; #Replace bomb with 0 as its now exploded.
  206.     }
  207.  
  208. return $zworkset;
  209. }
  210.  
  211.  
  212.  
  213. sub explode() {
  214.     my $input = $_[0];
  215.     my $count = $_[1];
  216.     my $pa;
  217.     my $pb;
  218.  
  219.     $count++;
  220.     ($pa, $pb) = split(",",$recursive{$input});
  221.  
  222.     if (($count == 5)&&($didexplode == 0)) { #We have dig 5 steps deep, which is 4 steps from the beginning as we increase $count in beginning of function.
  223.         $recursive{$input} = "#"; #Replace the pair with a bomb.
  224.         $didexplode = 1; #Permanently disable any further exploding.
  225.         $leftnum = $pa; #Save left num of pair.
  226.         $rightnum = $pb; #Save right num of pair.
  227.     }
  228.     else
  229.     {
  230.  
  231.         if ($pa =~ m/[a-zA-Z]+/) { #Any letters mean we need to dig deeper.
  232.             explode($pa, $count);
  233.         }
  234.         if ($pb =~ m/[a-zA-Z]+/) { #Any letters mean we need to dig deeper.
  235.             explode($pb, $count);
  236.         }
  237.     }
  238. }
  239.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement