Решение на Шеста задача от Николай Константинов

Обратно към всички решения

Към профила на Николай Константинов

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 18 успешни тест(а)
  • 0 неуспешни тест(а)

Код

# 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

Лог от изпълнението

..................

Finished in 0.51171 seconds
18 examples, 0 failures

История (1 версия и 0 коментара)

Николай обнови решението на 18.12.2011 16:41 (преди над 12 години)

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