[Haskell-cafe] Game of life in haskell.

Tony Finch dot at dotat.at
Tue Feb 2 20:17:57 EST 2010

On 3 Feb 2010, at 02:04, Jon Harrop <jon at ffconsultancy.com> wrote:
> On Tuesday 02 February 2010 23:54:58 Richard O'Keefe wrote:
>> One message in this thread has already pointed to a
>> solution (in C) that in effect uses a bit-packed sparse  
>> representation
>> to achieve high speed.  The point is that that approach takes time  
>> (and
>> space) per generation proportional to the number of occupied cells,
>> not the size of the space, and that is the basis of the "scaling"  
>> claim.
>> A simple Haskell analogue, which has the right asymptotic cost, would
>> be to represent a Life generation by a list of
>>    (row_number, [col_no, ..., col_no])
>> pairs in strictly ascending order of row number, where each pair
>> contains a list of the numbers of the occupied columns in strictly
>> ascending order.  The space is (number of occupied cells * a  
>> constant)
>> + (number of occupied rows * another constant).  Computing the next
>> generation then amounts to a bunch of 3-way merges.
> That will be a lot faster than using Map or Set but you're still  
> paying a lot
> for the indirections between cons cells. Mutating an array in-place  
> would be
> significantly faster and no more difficult to code correctly because  
> this is
> such a trivial algorithm.

Richard's description is pretty much exactly what I had in mind for a  
Haskell version of my C code. The C translates to Haskell so well  
because its data structure is immutable: the new generation is written  
to fresh memory then the old generation becomes garbage. The old  
generation is scanned in the order it is written (albeit by three  
pointers with a row between each one) which is inconvenient for linked  
lists. However the algorithm is symmetrical so it doesn't mind  
processing the universe in alternating directions, so long as the  
rendering code can cope :-) The indirections are less bad than they  
might be because the code will always be following a pointer to an  
adjacent memory location, because of the algorithm's simple allocation  
behaviour. But it'll be about twice as slow as the C equivalent  
because it uses twice the memory.

Efficient mutate-in-place Life algorithms become disgustingly  
complicated before they can beat listlife.

f.anthony.n.finch  <dot at dotat.at>  http://dotat.at/

More information about the Haskell-Cafe mailing list