ruby_as_apl

Conway's game of life in one statement of idiomatic Ruby... ported from APL

Stars
35
Committers
1

This repository contains implementation of Conway's Game of Life in one Ruby statement.

It was inspired by (in)famous APL's one-line implementation and is a more-or-less straightforward port of it into idiomatic Ruby.

To port the algorithm, a small prototype library with APL-style Array were createdso, technically, it is not a one-statement implementation, but I still prefer to think about it as "one-statement" one, as the class implemented is of generic use (somewhat like Numo::NArray), and operations used are familiar to any Rubyist.

You can read an explanatory article in my blog, but here we'll just show an implementation:

require 'apl'

AA = APL::Ary

def life(current_gen)
  current_gen.wrap
    .product(AA[-1, 0, 1], &:hrotate)
    .product(AA[-1, 0, 1], &:vrotate)
    .flatten(1).reduce(&:+)
    .eq(AA[3, 4])
    .zip(AA[1, current_gen], &:&)
    .reduce(&:|)
    .unwrap
end

...and its usage:

def show(grid)
  # APL-style AA#values_at(aa) produces array of items from the first array, taken and shaped
  # using numbers from second array as indexes.
  puts AA[' ', ''].values_at(grid)
end

glider = AA[1, 1, 1, 1, 0, 0, 0, 1, 0].reshape(3, 3)
grid = glider.take(-10, -10)

show grid.wrap
# 
#           
#           
#           
#           
#           
#           
#           
#        
#          
#          
# 


generations = [grid]
9.times { generations << life(generations.last) }

show AA[*generations]

# or, simpler, with 2.7's Enumerator#produce:

generations = Enumerator.produce(grid) { |cur| life(cur) }.take(10).map(&:wrap)
show AA[*generations]
#          
#                                                                                                              
#                                                                                                              
#                                                                                                              
#                                                                                                              
#                                                                                                             
#                                                                                                    
#                                                                                             
#                                                                                               
#                                                                                                        
#                                                                                                             
#