Advertisement
Guest User

Untitled

a guest
Dec 9th, 2021
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 5.16 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. $filename = "9.txt";
  4.  
  5. open(FILE, $filename);
  6. @data = <FILE>;
  7. close(FILE);
  8.  
  9. #Load input data into 2d array
  10.  
  11. for ($i = 0; $i < $#data + 1; $i++) {
  12.     $line = $data[$i];
  13.     $line =~ s/[^0-9]*//sgi;
  14.     @horz = split("", $line);
  15.     for ($z = 0; $z < $#horz + 1; $z++) {
  16.         $cell[$z][$i] = $horz[$z];
  17.     }
  18. }
  19.  
  20.  
  21. $xmax = $#horz + 1;
  22. $ymax = $#data + 1;
  23.  
  24. $heightdata = 0;
  25. $bcount = 0;
  26. @points = ();
  27.  
  28. #For loop intentionally not indented in a normal way as this is a composite loop to iterate through the 2d array.
  29.  
  30. for ($b = 0; $b < $ymax; $b++) {
  31. for ($a = 0; $a < $xmax; $a++) {
  32.  
  33.  
  34.     # For all adjacent cells, load in their value. If adjacent to edge, treat it as a "9" cell.
  35.     if (($a - 1) < 0) {
  36.         $left = 9;
  37.     }
  38.     else
  39.     {
  40.         $left = $cell[$a - 1][$b];
  41.     }
  42.     if (($b - 1) < 0) {
  43.         $top = 9;
  44.     }
  45.     else
  46.     {
  47.         $top = $cell[$a][$b - 1];
  48.     }
  49.  
  50.     if (($a + 1) > ($xmax - 1)) {
  51.         $right = 9;
  52.     }
  53.     else
  54.     {
  55.         $right = $cell[$a + 1][$b];
  56.     }
  57.     if (($b + 1) > ($ymax - 1)) {
  58.         $bottom = 9;
  59.     }
  60.     else
  61.     {
  62.         $bottom = $cell[$a][$b + 1];
  63.     }
  64.  
  65.     $current = $cell[$a][$b];
  66.  
  67.     if (($current < $left)&&($current < $right)&&($current < $top)&&($current < $bottom)) {
  68.         #Found the lowest point of a "basin".
  69.         $heightdata = $heightdata + $current + 1;
  70.         $bcount++;
  71.         push(@points, $a.",".$b);
  72.     }
  73.  
  74. }
  75. }
  76.  
  77. #Load in all "9" walls and all other as empty space.
  78.  
  79. for ($b = 0; $b < $ymax; $b++) {
  80. for ($a = 0; $a < $xmax; $a++) {
  81.     if ($cell[$a][$b] == 9) {
  82.         $cell[$a][$b] = "111";
  83.     }
  84.     else
  85.     {
  86.         $cell[$a][$b] = "222";
  87.     }
  88. }
  89. }
  90.  
  91.  
  92. $freenumber = "333";
  93.  
  94. @basin = ();
  95.  
  96.  
  97. #Give each lowest point a unique number starting from 333
  98.  
  99. foreach $p (@points) {
  100.     ($x, $y) = split(",", $p);
  101.     $cell[$x][$y] = $freenumber;
  102.     $freenumber++;
  103. }
  104.  
  105.  
  106. $modified = 1;
  107. $runcount = 0;
  108.  
  109.  
  110. # VERY hacky "Paint bucket function" consisting of a while loop that runs forever until no more changes can be made.
  111. while ($modified == 1) {
  112. $modified = 0;
  113.  
  114.     for ($b = 0; $b < $ymax; $b++) {
  115.     for ($a = 0; $a < $xmax; $a++) {
  116.  
  117.         #Same here, treat edge cells as having "111" walls.
  118.  
  119.         if (($a - 1) < 0) {
  120.             $left = "111";
  121.         }
  122.         else
  123.         {
  124.             $left = $cell[$a - 1][$b];
  125.         }
  126.         if (($b - 1) < 0) {
  127.             $top = "111";
  128.         }
  129.         else
  130.         {
  131.             $top = $cell[$a][$b - 1];
  132.         }
  133.  
  134.         if (($a + 1) > ($xmax - 1)) {
  135.             $right = "111";
  136.         }
  137.         else
  138.         {
  139.             $right = $cell[$a + 1][$b];
  140.         }
  141.         if (($b + 1) > ($ymax - 1)) {
  142.             $bottom = "111";
  143.         }
  144.         else
  145.         {
  146.             $bottom = $cell[$a][$b + 1];
  147.         }
  148.  
  149.  
  150.         #If cell is empty, check if any adjacent cell is both non-wall and non-empty. Then overwrite value in cell with that value.
  151.         if ($cell[$a][$b] eq "222") {
  152.             unless (($left =~ m/(222|111)/)&&($right =~ m/(222|111)/)&&($top =~ m/(222|111)/)&&($bottom =~ m/(222|111)/)) {
  153.                 unless ($left =~ m/(222|111)/) {
  154.                     $cell[$a][$b] = $left;
  155.                     $modified = 1;
  156.                 }
  157.                 unless ($right =~ m/(222|111)/) {
  158.                     $cell[$a][$b] = $right;
  159.                     $modified = 1;
  160.                 }
  161.                 unless ($top =~ m/(222|111)/) {
  162.                     $cell[$a][$b] = $top;
  163.                     $modified = 1;
  164.                 }
  165.                 unless ($bottom =~ m/(222|111)/) {
  166.                     $cell[$a][$b] = $bottom;
  167.                     $modified = 1;
  168.                 }
  169.  
  170.             }
  171.         }
  172.  
  173.     }
  174.     }
  175.  
  176.     #Run whole thing backwards - makes the while loop like a hundred times faster.
  177.  
  178.     for ($b = ($ymax - 1); $b > -1; $b--) {
  179.     for ($a = ($xmax - 1); $a > -1; $a--) {
  180.  
  181.         if (($a - 1) < 0) {
  182.             $left = "111";
  183.         }
  184.         else
  185.         {
  186.             $left = $cell[$a - 1][$b];
  187.         }
  188.         if (($b - 1) < 0) {
  189.             $top = "111";
  190.         }
  191.         else
  192.         {
  193.             $top = $cell[$a][$b - 1];
  194.         }
  195.  
  196.         if (($a + 1) > ($xmax - 1)) {
  197.             $right = "111";
  198.         }
  199.         else
  200.         {
  201.             $right = $cell[$a + 1][$b];
  202.         }
  203.         if (($b + 1) > ($ymax - 1)) {
  204.             $bottom = "111";
  205.         }
  206.         else
  207.         {
  208.             $bottom = $cell[$a][$b + 1];
  209.         }
  210.  
  211.  
  212.         if ($cell[$a][$b] eq "222") {
  213.             unless (($left =~ m/(222|111)/)&&($right =~ m/(222|111)/)&&($top =~ m/(222|111)/)&&($bottom =~ m/(222|111)/)) {
  214.                 unless ($left =~ m/(222|111)/) {
  215.                     $cell[$a][$b] = $left;
  216.                     $modified = 1;
  217.                 }
  218.                 unless ($right =~ m/(222|111)/) {
  219.                     $cell[$a][$b] = $right;
  220.                     $modified = 1;
  221.                 }
  222.                 unless ($top =~ m/(222|111)/) {
  223.                     $cell[$a][$b] = $top;
  224.                     $modified = 1;
  225.                 }
  226.                 unless ($bottom =~ m/(222|111)/) {
  227.                     $cell[$a][$b] = $bottom;
  228.                     $modified = 1;
  229.                 }
  230.  
  231.             }
  232.         }
  233.  
  234.     }
  235.     }
  236.  
  237. }
  238.  
  239. #Count number of basins using their unique number.
  240.  
  241. for ($b = 0; $b < $ymax; $b++) {
  242. for ($a = 0; $a < $xmax; $a++) {
  243.     $basin[$cell[$a][$b]]++;
  244. }
  245. }
  246.  
  247. $bigabasin = 0;
  248. $bigbbasin = 0;
  249. $bigcbasin = 0;
  250.  
  251. #Find 3 biggest basins:
  252.  
  253. for ($bascnt = 333; $bascnt < $freenumber; $bascnt++) {
  254.     if ($basin[$bascnt] > $bigabasin) {
  255.         $bigabasin = $basin[$bascnt];
  256.     }
  257. }
  258. for ($bascnt = 333; $bascnt < $freenumber; $bascnt++) {
  259.     if (($basin[$bascnt] > $bigbbasin)&&($basin[$bascnt] < $bigabasin)) {
  260.         $bigbbasin = $basin[$bascnt];
  261.     }
  262. }
  263. for ($bascnt = 333; $bascnt < $freenumber; $bascnt++) {
  264.     if (($basin[$bascnt] > $bigcbasin)&&($basin[$bascnt] < $bigbbasin)) {
  265.         $bigcbasin = $basin[$bascnt];
  266.     }
  267. }
  268.  
  269. #Print results.
  270.  
  271. print "\n";
  272. print $heightdata."\n";
  273. print $bcount."\n";
  274. print $freenumber."\n";
  275. print $bigabasin . "--" . $bigbbasin . "--" . $bigcbasin . "--" . ($bigabasin * $bigbbasin * $bigcbasin) . "\n";
  276.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement