This is just another life implementation.

It reads the initial life generation (generation 0) from stdin or a file
given on the command line.  The format is:


   .***...........***
   *..*..........*..*
   ...*....***......*
   ...*....*..*.....*
   *.*....*...*..*.*
   .......****
   ........*

That is, each line is a new row; * marks live cells, and any other character
marks dead cells.

Arguments are (when invoked with perl -s):

   -min=12   Don't start displaying until generation 12.
   -max=100  Run only up to generation 100.
   -ev=24    Display only every 24th generation.

Thus, to display only the 1000th generation, you can type

   perl -s rokicki1.pl -min=1000 -max=1000 00

The core algorithm is cute.  It runs in time proportional to the number of
live cells.  The size of the universe is about 2e9 in each dimension (and
this is limited by a constant defined early in the file so it can easily be
increased).

The core data structure is just a single list:

   Universe = (Rows* _ _)

(where _ represents a sentinel marking the end); each Row is

   Row = (_ y x0 x1 x2 ... xn)

so the length of this list is 2 + 2 * #rows + #oncells; quite compact.

To calculate the next generation, we simply do a single scan through this
list, maintaining three pointers to the current row/cell, previous row at
this x location, and next row at this location, keep track of how many
cells are on within a 3x3 rectangle, and build a new list containing the
next generation.  Very small, fast, and simple.

The obfuscation is done in about five stages.

The first stage simply tries to eliminate as much unnecessary code as
possible by eliminating if(a){b} (replacing it with a&&b) and such.  But
no major trickery here.

Next, all comments and whitespace is removed with a simple Perl filter.

Next, all variables are renamed with another simple Perl filter; this
renaming changes everything to single-character names.

Next, the file is `ASCII-compressed'.  A C program takes the ASCII text,
finds the most common ASCII pairs of characters, and replaces them with
an unused ASCII character, and repeats.  The dictionary so constructed is
tacked on to the front.  This makes a simple, ASCII, easy-to-decompress
version of the program.  (I could have used non-ASCII as well but figured
that would be mean.)  A very simple uncompressor using regular expressions
is tacked on to the front of the file.

Finally, the file is `white-space encoded'.  A Perl program converts each
character to eight characters of whitespace (mostly tabs and spaces, but
an occasional newline as well).  Again, a short decompressor is tacked on;
this time the decompressor has parts at the front (s##), end (the closing #,
+, and s##$_#eee; note *three* e's; this is cute) and the middle
(pack"b*",$_).  The three e's are needed because:

First e:   turn $_ into pack"b*",$_ (with lots of whitespace);
Second e:  execute the pack command, returning the ASCII-compressed script;
Third e:   execute the ASCII decompression and the program itself.

So why is this neat?

1.  It's got only a few total non-whitespace characters!  (about 26).
2.  It uses three e's (levels of execution).
3.  It's a cool, and even useful, LIFE algorithm.
4.  It's got many layers of obfuscation.
5.  After eliminating the whitespace trick, the resulting program is still
    less than 1024 characters.
