Advertisement
Guest User

Untitled

a guest
Dec 11th, 2020
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 11.41 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. $filename = "11.txt";
  4.  
  5. open(FILE, $filename);
  6. @data = <FILE>;
  7. close(FILE);
  8.  
  9. @seats = ();
  10.  
  11. $maxrow = $#data;
  12.  
  13. # Read in the file
  14. for ($a = 1; $a < ($maxrow + 2); $a++) {
  15.         $line = $data[$a-1];
  16.         $line =~ s/[^\.L]//sgi;
  17.         @seatrow = split("", $line);
  18.         $maxcolumn = $#seatrow;
  19.         for ($b = 1; $b < ($maxcolumn + 2); $b++) {
  20.                 $seats[$a][$b] = $seatrow[$b-1];
  21.         }
  22. }
  23.  
  24. #Put floor around all the seats
  25. for ($a = 0; $a < ($maxrow + 3); $a++) {
  26.         $seats[$a][0] = ".";
  27.         $seats[$a][$maxcolumn + 2] = ".";
  28. }
  29. for ($a = 0; $a < ($maxcolumn + 3); $a++) {
  30.         $seats[0][$a] = ".";
  31.         $seats[$maxrow + 2][$a] = ".";
  32. }
  33.  
  34. $changed = 1;
  35.  
  36. @oldseats = ();
  37. @ptseats = ();
  38.  
  39. #Make a copy of the 2-dimensional array (without references) for part2
  40. for ($a = 0; $a < ($maxrow + 3); $a++) {
  41.         for ($b = 0; $b < ($maxcolumn + 3); $b++) {
  42.                 $ptseats[$a][$b] = $seats[$a][$b];
  43.         }
  44. }
  45.  
  46. $rounds = 0;
  47.  
  48. #Loop until we make no changes.
  49. while ($changed == 1) {
  50.         $changed = 0;
  51.  
  52.         $rounds++;
  53.         #Make a copy of the previous round, so we can change seats without affecting the current round.
  54.         for ($a = 0; $a < ($maxrow + 3); $a++) {
  55.                 for ($b = 0; $b < ($maxcolumn + 3); $b++) {
  56.                         $oldseats[$a][$b] = $seats[$a][$b];
  57.                 }
  58.         }
  59.  
  60.  
  61.         for ($a = 1; $a < ($maxrow + 2); $a++) {
  62.                 for ($b = 1; $b < ($maxcolumn + 2); $b++) {
  63.  
  64.                         #Floor - skip
  65.                         if ($oldseats[$a][$b] eq ".") {
  66.                                 next;
  67.                         }
  68.  
  69.                         #Vacant seat
  70.                         if ($oldseats[$a][$b] eq "L") {
  71.  
  72.                                 $isocc = 0;
  73.  
  74.                                 #Check all 9 seats that is at the "cursor position". Since the middle seat isn't occupied, we don't need to except the middle seat from the checking.
  75.                                 for ($x = ($a - 1); $x < ($a + 2); $x++) {
  76.                                         for ($y = ($b - 1); $y < ($b + 2); $y++) {
  77.                                                 if ($oldseats[$x][$y] eq "#") {
  78.                                                         $isocc = 1;
  79.                                                 }
  80.                                         }
  81.                                 }
  82.  
  83.                                 if ($isocc == 0) {
  84.                                         # Set the seat as occupied
  85.                                         $seats[$a][$b] = "#";
  86.                                         $changed = 1;
  87.                                         next;
  88.                                 }
  89.                         }
  90.  
  91.                         #occupied seat
  92.                         if ($oldseats[$a][$b] eq "#") {
  93.  
  94.                                 $isocc = 0;
  95.                                 #Count the number of occupied seats in the 8 adjacent seats.
  96.                                 for ($x = ($a - 1); $x < ($a + 2); $x++) {
  97.                                         for ($y = ($b - 1); $y < ($b + 2); $y++) {
  98.                                                 #Skip the "cursor position"
  99.                                                 if (($x == $a)&&($y == $b)) {
  100.                                                         next;
  101.                                                 }
  102.                                                 if ($oldseats[$x][$y] eq "#") {
  103.                                                         $isocc++;
  104.                                                 }
  105.                                         }
  106.                                 }
  107.                                 #More than 3 seats (4 or more) - set the seat as vacant
  108.                                 if ($isocc > 3) {
  109.                                         $seats[$a][$b] = "L";
  110.                                         $changed = 1;
  111.                                 }
  112.                         }
  113.  
  114.                 # End of for loops
  115.                 }
  116.         }
  117. }
  118.  
  119. # Part1 run finished - count number of occupied seats.
  120.  
  121. $counter = 0;
  122.  
  123. for ($a = 0; $a < ($maxrow + 3); $a++) {
  124.         for ($b = 0; $b < ($maxcolumn + 3); $b++) {
  125.                 if ($seats[$a][$b] eq "#") {
  126.                         $counter++;
  127.                 }
  128.         }
  129. }
  130.  
  131. print "Part 1 completed in $rounds rounds.\n";
  132. print "P1: $counter \n";
  133.  
  134.  
  135. #Part 2 run
  136.  
  137. $changed = 1;
  138. @oldseats = ();
  139.  
  140. $rounds = 0;
  141.  
  142. #Loop until we make no changes
  143. while ($changed == 1) {
  144.         $rounds++;
  145.  
  146.         $changed = 0;
  147.  
  148.         # As before - make a copy so we can change seats without affecting the current round.
  149.         for ($a = 0; $a < ($maxrow + 3); $a++) {
  150.                 for ($b = 0; $b < ($maxcolumn + 3); $b++) {
  151.                         $oldseats[$a][$b] = $ptseats[$a][$b];
  152.                 }
  153.         }
  154.  
  155.         for ($a = 1; $a < ($maxrow + 2); $a++) {
  156.                 for ($b = 1; $b < ($maxcolumn + 2); $b++) {
  157.  
  158.                         # Floor - skip
  159.                         if ($oldseats[$a][$b] eq ".") {
  160.                                 next;
  161.                         }
  162.  
  163.  
  164.                         #Vacant seat
  165.                         if ($oldseats[$a][$b] eq "L") {
  166.  
  167.                                 $isocc = 0;
  168.  
  169.                                 #Loop through all positions adjacent to the seat - but this time, only relative positions.
  170.                                 for ($x = -1; $x < 2; $x++) {
  171.                                         for ($y = -1; $y < 2; $y++) {
  172.                                                 #If relative position means no change, skip
  173.                                                 if (($x == 0)&&($y == 0)) {
  174.                                                         next;
  175.                                                 }
  176.  
  177.                                                 # Shoot a "laser" in that direction. This by adding the relative change to the current "cursor" position.
  178.                                                 $tally = $b + $y;
  179.                                                 for ($d = $a + $x; (($d > 0)&&($d < ($maxrow + 3))); $d = $d + $x) {
  180.                                                         # If we go out of bounds in Y direction, end the for loop.
  181.                                                         # This means, that even if $x in the for loop is 0 - it will still not be a infinite loop.
  182.                                                         if (($tally < 1)||($tally > ($maxcolumn + 2))) {
  183.                                                                 last;
  184.                                                         }
  185.                                                         # If we stumble upon a vacant seat, end the for loop.
  186.                                                         if ($oldseats[$d][$tally] eq "L") {
  187.                                                                 last;
  188.                                                         }
  189.                                                         # If we stumble upon a occupied seat, set the flag and end for loop.
  190.                                                         if ($oldseats[$d][$tally] eq "#") {
  191.                                                                 $isocc = 1;
  192.                                                                 last;
  193.                                                         }
  194.                                                         #For each change in X direction, change also in Y direction.
  195.                                                         $tally = $tally + $y;
  196.                                                 }
  197.  
  198.                                         }
  199.                                 }
  200.                                 # If all "lasered" seats are vacant, set seat as occupied.
  201.                                 if ($isocc == 0) {
  202.                                         $ptseats[$a][$b] = "#";
  203.                                         $changed = 1;
  204.                                         next;
  205.                                 }
  206.                         }
  207.  
  208.                         # Occupied seat
  209.                         if ($oldseats[$a][$b] eq "#") {
  210.  
  211.                                 $isocc = 0;
  212.                                 # Same here, loop through all positions adjacent to the seat, but here, only saving relative positions.
  213.                                 for ($x = -1; $x < 2; $x++) {
  214.                                         for ($y = -1; $y < 2; $y++) {
  215.                                                 # If the relative position are no change, skip.
  216.                                                 if (($x == 0)&&($y == 0)) {
  217.                                                         next;
  218.                                                 }
  219.  
  220.                                                 # Shoot a "laser" in that direction. This by adding the relative change to the current "cursor" position.
  221.                                                 $tally = $b + $y;
  222.                                                 for ($d = $a + $x; (($d > 0)&&($d < ($maxrow + 3))); $d = $d + $x) {
  223.                                                         # If we go out of bounds in Y direction, end the for loop.
  224.                                                         # This means, that even if $x in the for loop is 0 - it will still not be a infinite loop.
  225.                                                         if (($tally < 1)||($tally > ($maxcolumn + 2))) {
  226.                                                                 last;
  227.                                                         }
  228.  
  229.                                                         #If we find a vacant seat, end the for loop.
  230.                                                         if ($oldseats[$d][$tally] eq "L") {
  231.                                                                 last;
  232.                                                         }
  233.                                                         #If we find a occupied seat, add to the count and end the for loop.
  234.                                                         if ($oldseats[$d][$tally] eq "#") {
  235.                                                                 $isocc++;
  236.                                                                 last;
  237.                                                         }
  238.                                                         #For each change in X direction, change also in Y direction.
  239.                                                         $tally = $tally + $y;
  240.                                                 }
  241.  
  242.                                         }
  243.                                 }
  244.                                 # If number of occupied seats exceed 4 (5 or more) then set the seat as vacant.
  245.                                 if ($isocc > 4) {
  246.                                         $ptseats[$a][$b] = "L";
  247.                                         $changed = 1;
  248.                                 }
  249.                         }
  250.  
  251.                 # End of for loops
  252.                 }
  253.         }
  254. }
  255.  
  256. #Finished part 2 run - Count number of occupied seats.
  257.  
  258. $counter = 0;
  259.  
  260. for ($a = 0; $a < ($maxrow + 3); $a++) {
  261.         for ($b = 0; $b < ($maxcolumn + 3); $b++) {
  262.                 if ($ptseats[$a][$b] eq "#") {
  263.                         $counter++;
  264.                 }
  265.         }
  266. }
  267.  
  268. print "Part 2 completed in $rounds rounds.\n";
  269. print "P2: $counter \n";
  270.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement