Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- $filename = "11.txt";
- open(FILE, $filename);
- @data = <FILE>;
- close(FILE);
- @seats = ();
- $maxrow = $#data;
- # Read in the file
- for ($a = 1; $a < ($maxrow + 2); $a++) {
- $line = $data[$a-1];
- $line =~ s/[^\.L]//sgi;
- @seatrow = split("", $line);
- $maxcolumn = $#seatrow;
- for ($b = 1; $b < ($maxcolumn + 2); $b++) {
- $seats[$a][$b] = $seatrow[$b-1];
- }
- }
- #Put floor around all the seats
- for ($a = 0; $a < ($maxrow + 3); $a++) {
- $seats[$a][0] = ".";
- $seats[$a][$maxcolumn + 2] = ".";
- }
- for ($a = 0; $a < ($maxcolumn + 3); $a++) {
- $seats[0][$a] = ".";
- $seats[$maxrow + 2][$a] = ".";
- }
- $changed = 1;
- @oldseats = ();
- @ptseats = ();
- #Make a copy of the 2-dimensional array (without references) for part2
- for ($a = 0; $a < ($maxrow + 3); $a++) {
- for ($b = 0; $b < ($maxcolumn + 3); $b++) {
- $ptseats[$a][$b] = $seats[$a][$b];
- }
- }
- $rounds = 0;
- #Loop until we make no changes.
- while ($changed == 1) {
- $changed = 0;
- $rounds++;
- #Make a copy of the previous round, so we can change seats without affecting the current round.
- for ($a = 0; $a < ($maxrow + 3); $a++) {
- for ($b = 0; $b < ($maxcolumn + 3); $b++) {
- $oldseats[$a][$b] = $seats[$a][$b];
- }
- }
- for ($a = 1; $a < ($maxrow + 2); $a++) {
- for ($b = 1; $b < ($maxcolumn + 2); $b++) {
- #Floor - skip
- if ($oldseats[$a][$b] eq ".") {
- next;
- }
- #Vacant seat
- if ($oldseats[$a][$b] eq "L") {
- $isocc = 0;
- #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.
- for ($x = ($a - 1); $x < ($a + 2); $x++) {
- for ($y = ($b - 1); $y < ($b + 2); $y++) {
- if ($oldseats[$x][$y] eq "#") {
- $isocc = 1;
- }
- }
- }
- if ($isocc == 0) {
- # Set the seat as occupied
- $seats[$a][$b] = "#";
- $changed = 1;
- next;
- }
- }
- #occupied seat
- if ($oldseats[$a][$b] eq "#") {
- $isocc = 0;
- #Count the number of occupied seats in the 8 adjacent seats.
- for ($x = ($a - 1); $x < ($a + 2); $x++) {
- for ($y = ($b - 1); $y < ($b + 2); $y++) {
- #Skip the "cursor position"
- if (($x == $a)&&($y == $b)) {
- next;
- }
- if ($oldseats[$x][$y] eq "#") {
- $isocc++;
- }
- }
- }
- #More than 3 seats (4 or more) - set the seat as vacant
- if ($isocc > 3) {
- $seats[$a][$b] = "L";
- $changed = 1;
- }
- }
- # End of for loops
- }
- }
- }
- # Part1 run finished - count number of occupied seats.
- $counter = 0;
- for ($a = 0; $a < ($maxrow + 3); $a++) {
- for ($b = 0; $b < ($maxcolumn + 3); $b++) {
- if ($seats[$a][$b] eq "#") {
- $counter++;
- }
- }
- }
- print "Part 1 completed in $rounds rounds.\n";
- print "P1: $counter \n";
- #Part 2 run
- $changed = 1;
- @oldseats = ();
- $rounds = 0;
- #Loop until we make no changes
- while ($changed == 1) {
- $rounds++;
- $changed = 0;
- # As before - make a copy so we can change seats without affecting the current round.
- for ($a = 0; $a < ($maxrow + 3); $a++) {
- for ($b = 0; $b < ($maxcolumn + 3); $b++) {
- $oldseats[$a][$b] = $ptseats[$a][$b];
- }
- }
- for ($a = 1; $a < ($maxrow + 2); $a++) {
- for ($b = 1; $b < ($maxcolumn + 2); $b++) {
- # Floor - skip
- if ($oldseats[$a][$b] eq ".") {
- next;
- }
- #Vacant seat
- if ($oldseats[$a][$b] eq "L") {
- $isocc = 0;
- #Loop through all positions adjacent to the seat - but this time, only relative positions.
- for ($x = -1; $x < 2; $x++) {
- for ($y = -1; $y < 2; $y++) {
- #If relative position means no change, skip
- if (($x == 0)&&($y == 0)) {
- next;
- }
- # Shoot a "laser" in that direction. This by adding the relative change to the current "cursor" position.
- $tally = $b + $y;
- for ($d = $a + $x; (($d > 0)&&($d < ($maxrow + 3))); $d = $d + $x) {
- # If we go out of bounds in Y direction, end the for loop.
- # This means, that even if $x in the for loop is 0 - it will still not be a infinite loop.
- if (($tally < 1)||($tally > ($maxcolumn + 2))) {
- last;
- }
- # If we stumble upon a vacant seat, end the for loop.
- if ($oldseats[$d][$tally] eq "L") {
- last;
- }
- # If we stumble upon a occupied seat, set the flag and end for loop.
- if ($oldseats[$d][$tally] eq "#") {
- $isocc = 1;
- last;
- }
- #For each change in X direction, change also in Y direction.
- $tally = $tally + $y;
- }
- }
- }
- # If all "lasered" seats are vacant, set seat as occupied.
- if ($isocc == 0) {
- $ptseats[$a][$b] = "#";
- $changed = 1;
- next;
- }
- }
- # Occupied seat
- if ($oldseats[$a][$b] eq "#") {
- $isocc = 0;
- # Same here, loop through all positions adjacent to the seat, but here, only saving relative positions.
- for ($x = -1; $x < 2; $x++) {
- for ($y = -1; $y < 2; $y++) {
- # If the relative position are no change, skip.
- if (($x == 0)&&($y == 0)) {
- next;
- }
- # Shoot a "laser" in that direction. This by adding the relative change to the current "cursor" position.
- $tally = $b + $y;
- for ($d = $a + $x; (($d > 0)&&($d < ($maxrow + 3))); $d = $d + $x) {
- # If we go out of bounds in Y direction, end the for loop.
- # This means, that even if $x in the for loop is 0 - it will still not be a infinite loop.
- if (($tally < 1)||($tally > ($maxcolumn + 2))) {
- last;
- }
- #If we find a vacant seat, end the for loop.
- if ($oldseats[$d][$tally] eq "L") {
- last;
- }
- #If we find a occupied seat, add to the count and end the for loop.
- if ($oldseats[$d][$tally] eq "#") {
- $isocc++;
- last;
- }
- #For each change in X direction, change also in Y direction.
- $tally = $tally + $y;
- }
- }
- }
- # If number of occupied seats exceed 4 (5 or more) then set the seat as vacant.
- if ($isocc > 4) {
- $ptseats[$a][$b] = "L";
- $changed = 1;
- }
- }
- # End of for loops
- }
- }
- }
- #Finished part 2 run - Count number of occupied seats.
- $counter = 0;
- for ($a = 0; $a < ($maxrow + 3); $a++) {
- for ($b = 0; $b < ($maxcolumn + 3); $b++) {
- if ($ptseats[$a][$b] eq "#") {
- $counter++;
- }
- }
- }
- print "Part 2 completed in $rounds rounds.\n";
- print "P2: $counter \n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement