Петко обнови решението на 18.12.2011 23:28 (преди около 13 години)
+# encoding: utf-8
+
+require 'enumerator'
+require 'forwardable'
+
+module GameOfLife
+ class Board
+ include Enumerable
+ extend Forwardable
+
+ OFFSETS = Array.new(9) {|i| [i/3 - 1, i%3 - 1]} - [[0, 0]]
+
+ def initialize(*cells)
+ @live_cells = Array(cells).uniq
+ end
+
+ def_delegator :@live_cells, :each
+
+ def [](x, y)
+ @live_cells.include? [x, y]
+ end
+
+ alias :alive? :[]
+
+ def next_generation
+ alive = possibly_alive.select {|cell| lives_tommorow(*cell)}
+ Board.new *alive
+ end
+
+ def count_neighbours(x, y)
+ count = 0
+ get_neighbours(x, y).each {|cell| count += 1 if alive? *cell}
+ count
+ end
+
+ def get_neighbours(x, y)
+ OFFSETS.inject([]) do |result, (offset_x, offset_y)|
+ result << [x+offset_x, y+offset_y]
+ end
+ end
+
+ def lives_tommorow(x, y)
+ return count_neighbours(x, y) == 3 if not alive? x, y
+ return false if count_neighbours(x, y) < 2
+ return true if count_neighbours(x, y) < 4
+ return false
+ end
+
+ def possibly_alive
+ @live_cells.inject(@live_cells.dup) do |result, cell|
+ result | get_neighbours(*cell)
+ end
+ end
+ end
+end