Syntactic Confectionery Delight PerlMonks

### comment on

 Need Help??

Update 1: Bit-manipulation will not work when \$y is negative. See this post. I assumed that \$y was always positive from testing using the initial test script.

Update 2: See this post for a version that maps two integers into one integer successfully.

For a last attempt in reaching 10x, I tried combining two integers into one via bit-manipulation. Having to support (\$x) being negative made bit-manipulation more complicated. However, it runs as fast as pack('ii').

This was an exercise and nothing more. I thought why not try bit-shifting the two integers into one.

```package Organism;

use strict;
# use warnings;

sub _pack {
my ( \$x, \$y ) = @_;
\$x < 0 ? -(abs(\$x) << 32 | \$y) : \$x << 32 | \$y;
}

sub _unpack {
my ( \$n ) = @_;
return \$n < 0
? ( -( abs(\$n) >> 32 ), abs(\$n) & 0xFFFFFFFF )
: (        \$n  >> 32  ,     \$n  & 0xFFFFFFFF );
}

sub count {
return scalar keys %{ shift->{Cells} };
}

# Input a list of [ x, y ] coords
sub insert_cells {
my \$cells = shift->{Cells};
for my \$r (@_) { \$cells->{ _pack @{\$r} } = undef }
}

# Used for verification and testing the state of the organism.
sub get_live_cells {
sort { \$a->[0] <=> \$b->[0] || \$a->[1] <=> \$b->[1] }
map { [ _unpack \$_ ] }
keys %{ shift->{Cells} };
}

sub tick {
my \$self  = shift;
my \$cells = \$self->{Cells};
my ( \$k1, \$k2, \$k3, \$k4, \$k5, \$k6, \$k7, \$k8,
\$x0, \$x1, \$x2, \$y0, \$y1, \$y2, %new_cells );

for my \$c (keys %{ \$cells }) {
# Get the (up to 8) dead cells surrounding the cell
( \$x0, \$y0 ) = \$c < 0
? ( -( abs(\$c) >> 32 ), abs(\$c) & 0xFFFFFFFF )
: (        \$c  >> 32  ,     \$c  & 0xFFFFFFFF );

( \$x1, \$x2, \$y1, \$y2 ) = ( \$x0 - 1, \$x0 + 1, \$y0 - 1, \$y0 + 1 );

my @zcells = (
(\$k1 = \$x1 < 0 ? -(abs(\$x1) << 32 | \$y1) : \$x1 << 32 | \$y1) x
+ !(exists \$cells->{\$k1}),
(\$k2 = \$x1 < 0 ? -(abs(\$x1) << 32 | \$y0) : \$x1 << 32 | \$y0) x
+ !(exists \$cells->{\$k2}),
(\$k3 = \$x1 < 0 ? -(abs(\$x1) << 32 | \$y2) : \$x1 << 32 | \$y2) x
+ !(exists \$cells->{\$k3}),
(\$k4 = \$x0 < 0 ? -(abs(\$x0) << 32 | \$y1) : \$x0 << 32 | \$y1) x
+ !(exists \$cells->{\$k4}),
(\$k5 = \$x0 < 0 ? -(abs(\$x0) << 32 | \$y2) : \$x0 << 32 | \$y2) x
+ !(exists \$cells->{\$k5}),
(\$k6 = \$x2 < 0 ? -(abs(\$x2) << 32 | \$y1) : \$x2 << 32 | \$y1) x
+ !(exists \$cells->{\$k6}),
(\$k7 = \$x2 < 0 ? -(abs(\$x2) << 32 | \$y0) : \$x2 << 32 | \$y0) x
+ !(exists \$cells->{\$k7}),
(\$k8 = \$x2 < 0 ? -(abs(\$x2) << 32 | \$y2) : \$x2 << 32 | \$y2) x
+ !(exists \$cells->{\$k8}) );

# Check the live cell
# Note: next line equivalent to nlive == 2 || nlive == 3
@zcells == 5 || @zcells == 6 and \$new_cells{\$c} = undef;

for my \$z (@zcells) {
( \$x0, \$y0 ) = \$z < 0
? ( -( abs(\$z) >> 32 ), abs(\$z) & 0xFFFFFFFF )
: (        \$z  >> 32  ,     \$z  & 0xFFFFFFFF );

( \$x1, \$x2, \$y1, \$y2 ) = ( \$x0 - 1, \$x0 + 1, \$y0 - 1, \$y0 + 1
+ );

# Get num live
(   ( exists \$cells->{ \$x1 < 0 ? -(abs(\$x1) << 32 | \$y1) : \$x
+1 << 32 | \$y1 } )
+ ( exists \$cells->{ \$x1 < 0 ? -(abs(\$x1) << 32 | \$y0) : \$x
+1 << 32 | \$y0 } )
+ ( exists \$cells->{ \$x1 < 0 ? -(abs(\$x1) << 32 | \$y2) : \$x
+1 << 32 | \$y2 } )
+ ( exists \$cells->{ \$x0 < 0 ? -(abs(\$x0) << 32 | \$y1) : \$x
+0 << 32 | \$y1 } )
+ ( exists \$cells->{ \$x0 < 0 ? -(abs(\$x0) << 32 | \$y2) : \$x
+0 << 32 | \$y2 } )
+ ( exists \$cells->{ \$x2 < 0 ? -(abs(\$x2) << 32 | \$y1) : \$x
+2 << 32 | \$y1 } )
+ ( exists \$cells->{ \$x2 < 0 ? -(abs(\$x2) << 32 | \$y0) : \$x
+2 << 32 | \$y0 } )
+ ( exists \$cells->{ \$x2 < 0 ? -(abs(\$x2) << 32 | \$y2) : \$x
+2 << 32 | \$y2 } )
) == 3 and \$new_cells{\$z} = undef;
}
}

\$self->{Cells} = \%new_cells;
}

sub new {
my \$class = shift;
my %init_self = ( Cells => {} );
bless \%init_self, \$class;
}

1;

Regards, Mario

In reply to Re^7: High Performance Game of Life by marioroy
in thread High Performance Game of Life by eyepopslikeamosquito

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":

• 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.
• Posts may use any of the Perl Monks Approved HTML tags:
a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, 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, 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?

Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (4)
As of 2024-07-14 17:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?

No recent polls found

Notices?
 • erzuuli ‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.