I don't have access to a 64-bit perl. However, this is a 32-bit version
of combining two 16 bit integers into a 32 bit number. While this runs
as long as the coordinates are within range, I can't test it in the 64-bit version.
I like it because all offsets are found with a simple addition inside tick.
All the encode/decode mess is in the input and output routines.
In theory (completely untested), all that's needed is to change the line
my $half = 16; # make 32 for 64-bit perls
to
my $half = 32; # make 32 for 64-bit perls
to make it use the full range of two 32 bit numbers.
So here's the code
package Organism;
use strict;
use warnings;
sub count {
return scalar keys %{ shift->{Cells} };
}
# Input a list of [ x, y ] coords
sub insert_cells {
my $self = shift;
my $cells = $self->{Cells};
for my $r (@_) { $cells->{
(($r->[0] + $self->{fudge}) << $self->{half}) |
($r->[1] + $self->{fudge})
} = undef }
}
# Return sorted list of cells in the Organism.
# Used for verification and testing the state of the organism.
sub get_live_cells {
my $self = shift;
sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] }
map { [
($_ >> $self->{half}) - $self->{fudge},
($_ & (1 << $self->{half}) - 1) - $self->{fudge}
] } keys %{ $self->{Cells} };
}
sub tick {
my $self = shift;
my $cells = $self->{Cells};
my @deltas = @{ $self->{deltas} };
my ( %new_cells, %dead_cells );
for my $c (keys %{ $cells }) {
# Get the (up to 8) dead cells surrounding the cell
$dead_cells{$_}++ for my @zcells =
grep !exists $cells->{$_}, map $c + $_, @deltas;
# Check the live cell
# Note: next line equivalent to nlive == 2 || nlive == 3
@zcells == 5 || @zcells == 6 and $new_cells{$c} = undef;
}
$dead_cells{$_} == 3 and $new_cells{$_} = undef for keys %dead_cell
+s;
$self->{Cells} = \%new_cells;
}
sub new {
my $class = shift;
my $half = 16; # make 32 for 64-bit perls
my $base = 1 << $half;
my $fudge = $base >> 1;
my @deltas = ($base-1, $base, $base+1,
-1, 1, -$base-1, -$base, -$base+1);
my %init_self = ( Cells => {},
fudge => $fudge, half => $half, deltas => \@deltas );
bless \%init_self, $class;
}
1;
Preliminary testing with 16 bit numbers seemed to show it's about 10% slower than the pack version :(
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
|
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.
|
|