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]
#
#
#
#
#
#
#
#
#
#
#
#