From: gaylord@UX1.CSO.UIUC.EDU
Newsgroups: sci.math.symbolic
Subject: leading a functional "Life"
Date: 14 Oct 92 13:02:03 GMT
Article-I.D.: ux1.199210141302.AA16915

i've been writing my computer simulation simulation column for that most
excellent publication "Mathematica in Education" an was messing about with
the "Game of Life" during the vice presidential debate last night (now i
now what the audience felt like at a roman gladiator match - incredible).

anyway, here's stuff i've come up with (this will be written up formally in
my column in a future issue of MiE - which btw is going to have, i
understand, electronic distribution arrangements - contact
Wellin@sonoma.edu for subscription details).

The package Life.m which comes with Mathematica is a good program, but as
with many M packages, i couldn't figure out how to run the thing (eg., what
are the imputs). i finally did figure it out and i 've re-organized the
code in the package so that it looks like what i think is a readable
program:

lifeGameMa[SIZE_Integer, t_Integer] := 
                Module[{},
                         initconfig = Table[Random[Integer], {SIZE}, {SIZE}] ;
                                periodicBC = Join[{Last[#]}, #, {First[#]}]& ;
                         LifeRule[list_] := Module[{k},
                                            k = Count[list, 1, {2}] ;
                                            If[(list[[2, 2]] == 1 && k ==
4)||k == 3, 1, 0]
                                            ] ;
                         LifeUpdate[list_] := Map[LifeRule, 
                         
Partition[periodicBC[Map[periodicBC,list]],{3,3},{1,1}],{2}];
                         LifeEvolve = NestList[LifeUpdate,initconfig,t];
                                
                         Do[ 
       Show[Graphics[RasterArray[Reverse[
          LifeEvolve[[i]]/.{1->RGBColor[0,1,0],
                            0->RGBColor[1,0,1]}]]]],
                                 {i,t+1}
                                 ]                              
                                                ]                          
                                                                    

note: the only changes from the code in the package is that i use the term
periodicBC and i've changed the graphics from the wierd Cubiod  which gives
me a severe headache (why a 3D portrayal of a 2D world anyway?) to
RasterArray (btw - i have no luck printing out RasterArray -is it a bug in
only the Mac version or everywhere?).

for those who are not able to read this code [although you can make up your
own initconfig and run through each step line-by-line], basically,
Partition is being used to create out the matrix (which is the 'gameboard')
which has been 'wrapped' with periodic b.c., the submatrices consisting of
each site and its nearest neighbors, to which the life & death rules are
then applied.

This is essentially good functional code. However it can be made much
faster (>3X) and better-looking by following: 

the dictum of John W. Gray for functional programming:

"Deal with mathematical strucutres as wholes.
Never tear them apart and rebuild them again."

this is equivalent to using "the power of large values" which is how Sam
Kamin characterizes the APL language. 

We can write the Life" program without having to 'wrap' the gameboard and
without having to create any submatrices:

here's the program:

lifeGameAPL[SIZE_Integer, t_Integer] := 
                Module[{},
                         initconfig = Table[Random[Integer], {SIZE}, {SIZE}] ;
                         rr[m_List,n_Integer] := RotateLeft[m,n] ;
                         cr[m_List,n_Integer] :=
Transpose[RotateLeft[Transpose[m],n]];
                         nn[m_List] :=
cr[m,1]+cr[m,-1]+rr[m,1]+rr[m,-1]+cr[rr[m,1],1]+
                                      
cr[rr[m,1],-1]+rr[cr[m,-1],-1]+rr[cr[m,1],-1] ;
                   
                  LifeEvolve = 
                  FixedPointList[
                     (Map[Function[y, If[4 < y < 8, 1, 0]], 
                                          (# + 2 nn[#]),{2}])&, initconfig, t];
                                
                         Map[(Show[Graphics[RasterArray[Reverse[
                           LifeEvolve[[#]]/.{1->RGBColor[0,1,0],
                                             0->RGBColor[1,0,1]}]]]])&,
                                                       
Range[Length[LifeEvolve]]]                              
                                                ]                          
                                                                      

the only thing i've done to the graphics that's different from the first
program is that i've used Map[..#..&, Range[]] instead of a Do loop (i hate
Do Loops !).

as for what's going on: suffice it (until your read the column i nMiE) to
say, that I create 8 rotated gameboards, add them up, multiply by two, add
the result to the original game board and use the rule that values of 5,6,7
lead to birth or continued life while all other values result in death.
also, FixedPointList lets me use total extinction to end the run.

that's it; i'm pretty self-satisfied with this program but always welcome
improvements and comments.

richard j. gaylord, university of illinois, gaylord@ux1.cso.uiuc.edu

"if you're not programming functionally, then you must be programming
dysfunctionally"
Newsgroups: sci.math.symbolic