Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- $filename = "9.txt";
- open(FILE, $filename);
- @data = <FILE>;
- close(FILE);
- #Load input data into 2d array
- for ($i = 0; $i < $#data + 1; $i++) {
- $line = $data[$i];
- $line =~ s/[^0-9]*//sgi;
- @horz = split("", $line);
- for ($z = 0; $z < $#horz + 1; $z++) {
- $cell[$z][$i] = $horz[$z];
- }
- }
- $xmax = $#horz + 1;
- $ymax = $#data + 1;
- $heightdata = 0;
- $bcount = 0;
- @points = ();
- #For loop intentionally not indented in a normal way as this is a composite loop to iterate through the 2d array.
- for ($b = 0; $b < $ymax; $b++) {
- for ($a = 0; $a < $xmax; $a++) {
- # For all adjacent cells, load in their value. If adjacent to edge, treat it as a "9" cell.
- if (($a - 1) < 0) {
- $left = 9;
- }
- else
- {
- $left = $cell[$a - 1][$b];
- }
- if (($b - 1) < 0) {
- $top = 9;
- }
- else
- {
- $top = $cell[$a][$b - 1];
- }
- if (($a + 1) > ($xmax - 1)) {
- $right = 9;
- }
- else
- {
- $right = $cell[$a + 1][$b];
- }
- if (($b + 1) > ($ymax - 1)) {
- $bottom = 9;
- }
- else
- {
- $bottom = $cell[$a][$b + 1];
- }
- $current = $cell[$a][$b];
- if (($current < $left)&&($current < $right)&&($current < $top)&&($current < $bottom)) {
- #Found the lowest point of a "basin".
- $heightdata = $heightdata + $current + 1;
- $bcount++;
- push(@points, $a.",".$b);
- }
- }
- }
- #Load in all "9" walls and all other as empty space.
- for ($b = 0; $b < $ymax; $b++) {
- for ($a = 0; $a < $xmax; $a++) {
- if ($cell[$a][$b] == 9) {
- $cell[$a][$b] = "111";
- }
- else
- {
- $cell[$a][$b] = "222";
- }
- }
- }
- $freenumber = "333";
- @basin = ();
- #Give each lowest point a unique number starting from 333
- foreach $p (@points) {
- ($x, $y) = split(",", $p);
- $cell[$x][$y] = $freenumber;
- $freenumber++;
- }
- $modified = 1;
- $runcount = 0;
- # VERY hacky "Paint bucket function" consisting of a while loop that runs forever until no more changes can be made.
- while ($modified == 1) {
- $modified = 0;
- for ($b = 0; $b < $ymax; $b++) {
- for ($a = 0; $a < $xmax; $a++) {
- #Same here, treat edge cells as having "111" walls.
- if (($a - 1) < 0) {
- $left = "111";
- }
- else
- {
- $left = $cell[$a - 1][$b];
- }
- if (($b - 1) < 0) {
- $top = "111";
- }
- else
- {
- $top = $cell[$a][$b - 1];
- }
- if (($a + 1) > ($xmax - 1)) {
- $right = "111";
- }
- else
- {
- $right = $cell[$a + 1][$b];
- }
- if (($b + 1) > ($ymax - 1)) {
- $bottom = "111";
- }
- else
- {
- $bottom = $cell[$a][$b + 1];
- }
- #If cell is empty, check if any adjacent cell is both non-wall and non-empty. Then overwrite value in cell with that value.
- if ($cell[$a][$b] eq "222") {
- unless (($left =~ m/(222|111)/)&&($right =~ m/(222|111)/)&&($top =~ m/(222|111)/)&&($bottom =~ m/(222|111)/)) {
- unless ($left =~ m/(222|111)/) {
- $cell[$a][$b] = $left;
- $modified = 1;
- }
- unless ($right =~ m/(222|111)/) {
- $cell[$a][$b] = $right;
- $modified = 1;
- }
- unless ($top =~ m/(222|111)/) {
- $cell[$a][$b] = $top;
- $modified = 1;
- }
- unless ($bottom =~ m/(222|111)/) {
- $cell[$a][$b] = $bottom;
- $modified = 1;
- }
- }
- }
- }
- }
- #Run whole thing backwards - makes the while loop like a hundred times faster.
- for ($b = ($ymax - 1); $b > -1; $b--) {
- for ($a = ($xmax - 1); $a > -1; $a--) {
- if (($a - 1) < 0) {
- $left = "111";
- }
- else
- {
- $left = $cell[$a - 1][$b];
- }
- if (($b - 1) < 0) {
- $top = "111";
- }
- else
- {
- $top = $cell[$a][$b - 1];
- }
- if (($a + 1) > ($xmax - 1)) {
- $right = "111";
- }
- else
- {
- $right = $cell[$a + 1][$b];
- }
- if (($b + 1) > ($ymax - 1)) {
- $bottom = "111";
- }
- else
- {
- $bottom = $cell[$a][$b + 1];
- }
- if ($cell[$a][$b] eq "222") {
- unless (($left =~ m/(222|111)/)&&($right =~ m/(222|111)/)&&($top =~ m/(222|111)/)&&($bottom =~ m/(222|111)/)) {
- unless ($left =~ m/(222|111)/) {
- $cell[$a][$b] = $left;
- $modified = 1;
- }
- unless ($right =~ m/(222|111)/) {
- $cell[$a][$b] = $right;
- $modified = 1;
- }
- unless ($top =~ m/(222|111)/) {
- $cell[$a][$b] = $top;
- $modified = 1;
- }
- unless ($bottom =~ m/(222|111)/) {
- $cell[$a][$b] = $bottom;
- $modified = 1;
- }
- }
- }
- }
- }
- }
- #Count number of basins using their unique number.
- for ($b = 0; $b < $ymax; $b++) {
- for ($a = 0; $a < $xmax; $a++) {
- $basin[$cell[$a][$b]]++;
- }
- }
- $bigabasin = 0;
- $bigbbasin = 0;
- $bigcbasin = 0;
- #Find 3 biggest basins:
- for ($bascnt = 333; $bascnt < $freenumber; $bascnt++) {
- if ($basin[$bascnt] > $bigabasin) {
- $bigabasin = $basin[$bascnt];
- }
- }
- for ($bascnt = 333; $bascnt < $freenumber; $bascnt++) {
- if (($basin[$bascnt] > $bigbbasin)&&($basin[$bascnt] < $bigabasin)) {
- $bigbbasin = $basin[$bascnt];
- }
- }
- for ($bascnt = 333; $bascnt < $freenumber; $bascnt++) {
- if (($basin[$bascnt] > $bigcbasin)&&($basin[$bascnt] < $bigbbasin)) {
- $bigcbasin = $basin[$bascnt];
- }
- }
- #Print results.
- print "\n";
- print $heightdata."\n";
- print $bcount."\n";
- print $freenumber."\n";
- print $bigabasin . "--" . $bigbbasin . "--" . $bigcbasin . "--" . ($bigabasin * $bigbbasin * $bigcbasin) . "\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement