Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- $| = 1;
- my @DIRS = ([-1,-1], [-1,0], [-1,1], [ 0,-1], [ 0,1], [ 1,-1], [ 1,0], [ 1,1]);
- # Read Grid into buffer adding spaces for quick and easy boundary handling
- # Grid[ buffer ][ ycoord ][ xcoord ]
- my @Grid = [map { chomp; [' ', split(//), ' '] } <>];
- my $X_SIZE = @{$Grid[0][0]};
- # borders for the top and bottom
- unshift( @{$Grid[0]}, [(' ') x $X_SIZE] );
- push( @{$Grid[0]}, [(' ') x $X_SIZE] );
- my $Y_SIZE = @{$Grid[0]};
- # initialize other buffer
- $Grid[1] = [ map { [(' ') x $X_SIZE] } (0 .. $Y_SIZE) ];
- # for swapping between old and new buffers
- my ($old, $new) = (0, 1);
- # Return count of adjacent occupied squares
- sub get_occupied {
- my ($y, $x) = @_;
- my $ret = 0;
- foreach my $d (@DIRS) {
- my ($ny, $nx) = ($y + $d->[0], $x + $d->[1]);
- while ($Grid[$old][$ny][$nx] eq '.') {
- ($ny, $nx) = ($ny + $d->[0], $nx + $d->[1]);
- }
- $ret += ($Grid[$old][$ny][$nx] eq '#');
- }
- return ($ret);
- }
- #
- # Main loop
- #
- my ($gen, $changes, $total_occ) = (0,1,0);
- while ($changes) {
- ($changes, $total_occ) = (0,0);
- for (my $y = 1; $y < $Y_SIZE - 1; $y++) {
- for (my $x = 1; $x < $X_SIZE - 1; $x++) {
- my $occ = &get_occupied( $y, $x );
- if ($Grid[$old][$y][$x] eq 'L' && $occ == 0) {
- $Grid[$new][$y][$x] = '#';
- $changes++;
- } elsif ($Grid[$old][$y][$x] eq '#' && $occ >= 5) {
- $Grid[$new][$y][$x] = 'L';
- $changes++;
- } else {
- $Grid[$new][$y][$x] = $Grid[$old][$y][$x];
- }
- $total_occ += ($Grid[$new][$y][$x] eq '#');
- }
- }
- printf( "Generation: %4d Occupied: %4d Changes: %4d\r",
- ++$gen, $total_occ, $changes );
- ($old, $new) = ($new, $old);
- }
- print "\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement