Neat hack. Here's a command to (almost) convert it to RLE:
Code: Select all
dc -e"[q]sQ[_1sx]s.?sxsylxn[bo]n[?z1=Qrdly-dn[$]n0<.sydlx-1-n[bo]nsxdx]dx[!]p"
For the glider cell list it produces "0bo0$1bo1$1bo0$0bo1$1bo!". The 0s present a problem; 0b probably works on some (most?) decoders, but 0$, at least on mine, resets the x value to 0, like a carriage return with no linefeed. I could do "| sed s/0[b$]//g" but that would turn, say, "20bo" into "2o". I haven't figured out how to properly sanitise this, help would be appreciated. Also it doesn't work if there's a cell with an x value less than 0.
Also here's a C version for n00bs who can't read dc fluently (is there a way to reorganise this so there's only one scanf?):
Code: Select all
/* cell list to run length encoding */
#include <stdio.h>
int main(){
int x,y,
ox,oy; /* old xy */
scanf("%d %d",&y,&x);
ox=-1,oy=y;
do {
printf("%d$",y-oy);
if(y-oy) ox=-1;
printf("%dbo",x-ox-1);
ox=x,oy=y;
} while(scanf("%d %d",&y,&x)!=EOF);
putchar('\n');
return 0;
}
I believe there is no constant-memory algorithm to simulate the game of life on a stream. You'd need to keep a buffer of the last 2 lines in memory which can be arbitrarily large. On multiple streams simultaneously, though, I think it's possible. Consider breaking up the cell list into 3 files like so:
Code: Select all
perl -e '
open my $a, ">", "a";
open my $b, ">", "b";
open my $c, ">", "c";
while(<STDIN>){
my ($y,$x) = /(\d+) (\d+)/;
if ($y%3 == 0) { print $a $y," ",$x,"\n"; }
if ($y%3 == 1) { print $b $y," ",$x,"\n"; }
if ($y%3 == 2) { print $c $y," ",$x,"\n"; }
}'
i.e. There are three files, 'a', 'b', and 'c', which contain alternating rows (mod 3). If you do 3 passes on these 3 files, you could compute the next generation as another set of 3 files, I think.