Решение на Шеста задача от Петър Костов

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

Към профила на Петър Костов

Резултати

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

Код

# encoding: UTF-8
module GameOfLife
class Cell
attr_reader :x, :y
attr_accessor :alive
def initialize(x, y, alive = true)
@x = x
@y = y
@alive = alive
end
def to_a
[x, y]
end
end
class Rules
def self.applay_rules(neighbors_count, cell)
if not cell.alive and neighbors_count == 3
cell.alive = true
elsif cell.alive and neighbors_count < 2
cell.alive = false
elsif cell.alive and neighbors_count > 3
cell.alive = false
end
end
end
class RangeTable
include Enumerable
def initialize(board)
@board = board
init_range
end
def each
(@min_x..@max_x).each do |x|
(@min_y..@max_y).each do |y|
yield @board.get_cell(x, y).clone
end
end
end
def neighbors(cell)
neighbors = []
cross_neighbors(neighbors, cell.x, cell.y)
x_neighbors(neighbors, cell.x, cell.y)
neighbors
end
private
def init_range
@min_x = @board.collect { |x, y| x}.min - 1
@max_x = @board.collect { |x, y| x}.max + 1
@min_y = @board.collect { |x, y| y}.min - 1
@max_y = @board.collect { |x, y| y}.max + 1
end
def cross_neighbors(neighbors, x, y)
neighbors << @board.get_cell(x+1, y) if @board[x+1, y]
neighbors << @board.get_cell(x-1, y) if @board[x-1, y]
neighbors << @board.get_cell(x, y+1) if @board[x, y+1]
neighbors << @board.get_cell(x, y-1) if @board[x, y-1]
end
def x_neighbors(neighbors, x, y)
neighbors << @board.get_cell(x+1, y+1) if @board[x+1, y+1]
neighbors << @board.get_cell(x-1, y+1) if @board[x-1, y+1]
neighbors << @board.get_cell(x+1, y-1) if @board[x+1, y-1]
neighbors << @board.get_cell(x-1, y-1) if @board[x-1, y-1]
end
end
class NextGeneration
def initialize(board)
@board = board
@range_table = RangeTable.new(@board)
end
def next_generation
cells = select_cells
Board.new(*cells.map { |cell| cell.to_a })
end
private
def select_cells
@range_table.select do |cell|
Rules.applay_rules(@range_table.neighbors(cell).size, cell)
cell.alive == true
end
end
end
class Board
include Enumerable
attr_reader :cells
def initialize(*cells)
@cells = []
cells.each { |cell| @cells << Cell.new(cell[0], cell[1]) if not self[cell[0], cell[1]]}
end
def each
@cells.each { |cell| yield cell.x, cell.y}
end
def [](x, y)
get_cell(x, y).alive
end
def count
cells.size
end
def next_generation
return Board.new if count == 0
next_gen = NextGeneration.new(self)
next_gen.next_generation
end
def get_cell(x, y)
@cells.select { |cell| cell.x == x and cell.y == y }.fetch(0, Cell.new(x, y, false))
end
end
end

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

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

Finished in 0.39291 seconds
18 examples, 0 failures

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

Петър обнови решението на 19.12.2011 12:35 (преди около 13 години)

+# encoding: UTF-8
+module GameOfLife
+ class Cell
+ attr_reader :x, :y
+ attr_accessor :alive
+
+ def initialize(x, y, alive = true)
+ @x = x
+ @y = y
+ @alive = alive
+ end
+
+ def to_a
+ [x, y]
+ end
+ end
+
+ class Rules
+ def self.applay_rules(neighbors_count, cell)
+ if not cell.alive and neighbors_count == 3
+ cell.alive = true
+ elsif cell.alive and neighbors_count < 2
+ cell.alive = false
+ elsif cell.alive and neighbors_count > 3
+ cell.alive = false
+ end
+ end
+
+ end
+
+ class RangeTable
+ include Enumerable
+
+ def initialize(board)
+ @board = board
+ init_range
+ end
+
+ def each
+ (@min_x..@max_x).each do |x|
+ (@min_y..@max_y).each do |y|
+ yield @board.get_cell(x, y).clone
+ end
+ end
+ end
+
+ def neighbors(cell)
+ neighbors = []
+ cross_neighbors(neighbors, cell.x, cell.y)
+ x_neighbors(neighbors, cell.x, cell.y)
+ neighbors
+ end
+
+ private
+
+ def init_range
+ @min_x = @board.collect { |x, y| x}.min - 1
+ @max_x = @board.collect { |x, y| x}.max + 1
+ @min_y = @board.collect { |x, y| y}.min - 1
+ @max_y = @board.collect { |x, y| y}.max + 1
+ end
+
+ def cross_neighbors(neighbors, x, y)
+ neighbors << @board.get_cell(x+1, y) if @board[x+1, y]
+ neighbors << @board.get_cell(x-1, y) if @board[x-1, y]
+ neighbors << @board.get_cell(x, y+1) if @board[x, y+1]
+ neighbors << @board.get_cell(x, y-1) if @board[x, y-1]
+ end
+
+ def x_neighbors(neighbors, x, y)
+ neighbors << @board.get_cell(x+1, y+1) if @board[x+1, y+1]
+ neighbors << @board.get_cell(x-1, y+1) if @board[x-1, y+1]
+ neighbors << @board.get_cell(x+1, y-1) if @board[x+1, y-1]
+ neighbors << @board.get_cell(x-1, y-1) if @board[x-1, y-1]
+ end
+ end
+
+ class NextGeneration
+ def initialize(board)
+ @board = board
+ @range_table = RangeTable.new(@board)
+ end
+
+ def next_generation
+ cells = select_cells
+ Board.new(*cells.map { |cell| cell.to_a })
+ end
+
+ private
+
+ def select_cells
+ @range_table.select do |cell|
+ Rules.applay_rules(@range_table.neighbors(cell).size, cell)
+ cell.alive == true
+ end
+ end
+
+ end
+
+ class Board
+ include Enumerable
+
+ attr_reader :cells
+
+ def initialize(*cells)
+ @cells = []
+ cells.each { |cell| @cells << Cell.new(cell[0], cell[1]) if not self[cell[0], cell[1]]}
+ end
+
+ def each
+ @cells.each { |cell| yield cell.x, cell.y}
+ end
+
+ def [](x, y)
+ get_cell(x, y).alive
+ end
+
+ def count
+ cells.size
+ end
+
+ def next_generation
+ return Board.new if count == 0
+ next_gen = NextGeneration.new(self)
+ next_gen.next_generation
+ end
+
+ def get_cell(x, y)
+ @cells.select { |cell| cell.x == x and cell.y == y }.fetch(0, Cell.new(x, y, false))
+ end
+
+ end
+end