Николай обнови решението на 18.12.2011 16:41 (преди около 13 години)
+# encoding: utf-8
+
+module GameOfLife
+
+ class Board
+ include Enumerable
+ attr_reader :cells
+
+ def initialize *arrays
+ @cells = []
+ if arrays == [] then return end
+ arrays = arrays.uniq
+ arrays.map { |c| @cells << Cell.new(c[0], c[1]) }
+ end
+
+ def [] x, y
+ @cells.one? { |c| [c.x, c.y].eql? [x, y] }
+ end
+
+ def each &blck
+ @cells.each { |c| yield c.x, c.y }
+ end
+
+ def count
+ @cells.count
+ end
+
+ def next_generation
+ not_dying = ::Rules::NotDyingOnes.add_cells self
+ all_alive = ::Rules::ReproductionOnes.add_cells self, not_dying
+
+ Board.new *all_alive
+ end
+
+ def to_a
+ array = []
+ self.each { |x, y| array << [x, y] }
+
+ array
+ end
+
+ def collect &blck
+ array = []
+ self.to_a.map { |element| array << (yield element) }
+
+ array
+ end
+ end
+
+ class Cell
+ attr_reader :x, :y
+
+ def initialize(x, y)
+ @x = x
+ @y = y
+ end
+
+ end
+
+ class Neighbour
+ attr_reader :neighbours
+
+ def initialize x, y
+ @neighbours = []
+ init_first_half_of_neighbours x, y
+ init_second_half_of_neighbours x, y
+ end
+
+ def init_first_half_of_neighbours x, y
+ @neighbours << Cell.new(x - 1, y)
+ @neighbours << Cell.new(x + 1, y)
+ @neighbours << Cell.new(x, y + 1)
+ @neighbours << Cell.new(x, y - 1)
+ end
+
+ def init_second_half_of_neighbours x, y
+ @neighbours << Cell.new(x - 1, y - 1)
+ @neighbours << Cell.new(x - 1, y + 1)
+ @neighbours << Cell.new(x + 1, y - 1)
+ @neighbours << Cell.new(x + 1, y + 1)
+ end
+ end
+
+end
+
+module Rules
+
+ class NotDyingOnes
+
+ def self.add_cells board
+ list = []
+ board.each do |x, y|
+ neighbours = ::GameOfLife::Neighbour.new(x, y).neighbours
+ length = neighbours.find_all { |n| board[n.x, n.y] }.length
+ list << [x, y] if (2..3).include? length
+ end
+
+ list
+ end
+
+ end
+
+ class ReproductionOnes
+
+ def self.add_cells board, list
+ board.each do |x, y|
+ neighbours = ::GameOfLife::Neighbour.new(x, y).neighbours
+ neighbours.each do |neighbour|
+ collect_becoming_alive_cells board, neighbour, list
+ end
+ end
+
+ list
+ end
+
+ def self.collect_becoming_alive_cells board, neighbour, list
+ unless board[neighbour.x, neighbour.y]
+ neighbours = ::GameOfLife::Neighbour.new(neighbour.x, neighbour.y).neighbours
+ length = neighbours.find_all { |n| board[n.x, n.y] }.length
+ list << [neighbour.x, neighbour.y] if length == 3
+ end
+ end
+
+ end
+
+end