Генади обнови решението на 15.12.2011 21:34 (преди около 13 години)
+require 'set'
+
+module GameOfLife
+ class Board
+ include Enumerable
+
+ def initialize(*cells)
+ @cells = Set.new(cells)
+ end
+
+ def count
+ @cells.size
+ end
+
+ def each(&block)
+ @cells.each(&block)
+ end
+
+ def [](x, y)
+ @cells.include?([x, y])
+ end
+
+ def next_generation
+ Generation.new(self).next_board
+ end
+ end
+
+ class Generation
+ def initialize(board)
+ @cells = board
+ .map { |x, y| Cell.new(x, y, from: board) }
+ .map { |cell| [cell] + cell.neighbours }
+ .flatten
+ end
+
+ def next_board
+ Board.new(*@cells.select { |cell| cell.should_live? }.map(&:to_a))
+ end
+ end
+
+ class Cell
+ def initialize(x, y, options = {})
+ @x, @y = x, y
+ @board = options[:from]
+ end
+
+ def neighbours
+ [[-1, 1], [0, 1], [1, 1], [-1, 0], [1, 0], [-1, -1], [0, -1], [1, -1]].map do |x, y|
+ Cell.new(@x + x, @y + y, from: @board)
+ end
+ end
+
+ def alive?
+ @board[@x, @y]
+ end
+
+ def should_live?
+ alive_neighbours = neighbours.select { |cell| cell.alive? }.size
+ alive? ? (2..3) === alive_neighbours : alive_neighbours == 3
+ end
+
+ def to_a
+ [@x, @y]
+ end
+ end
+end