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

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

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

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 16 успешни тест(а)
  • 2 неуспешни тест(а)

Код

module BoardEnumerable
include Enumerable
def each &block
@field.each_with_index { |elem, ind| each_yield elem, ind, &block }
end
def count
@field.flatten.count { |elem| elem == true }
end
private
def each_yield array, index
array.each_index do |pos|
yield index, pos if array[pos] == true
end
end
end
module GameOfLife
class NeighbourGenerator
def initialize field
@field = field
end
def get_neighbours x, y
neigh = []
neigh << [left(x,y), right(x,y)]
neigh << [top(x,y), top_left(x,y), top_right(x,y)]
(neigh + [bottom(x,y), bottom_left(x,y), bottom_right(x,y)]).flatten
end
private
def left x, y
y < 1 ? false : @field[x][y-1]
end
def right x, y
@field[x][y+1] == nil ? false : @field[x][y+1]
end
def top x, y
x < 1 ? false : @field[x-1][y]
end
def top_left x, y
(x < 1 or y < 1) ? false : @field[x-1][y-1]
end
def top_right x, y
return false if x < 1
@field[x-1][y+1] == nil ? false : @field[x-1][y+1]
end
def bottom x, y
@field[x+1] == nil ? false : @field[x+1][y]
end
def bottom_left x, y
return false if @field[x+1] == nil
y < 1 ? false : @field[x+1][y-1]
end
def bottom_right x, y
return false if @field[x+1] == nil
@field[x+1][y+1] == nil ? false : @field[x+1][y+1]
end
end
class GenerationGenerator
def initialize past_gen_field
@current_field = past_gen_field
@neigh_gen = NeighbourGenerator.new @current_field
end
def produce_generation
Board.new produce_living
end
private
def count_alive array
array.count { |cell| cell == true }
end
def produce_living
living_arr = []
@current_field.each_with_index do |row, row_index|
living_arr += living_from_row(row, row_index)
end
living_arr
end
def living_from_row row, row_index
living_in_row = []
row.each_with_index do |elem, pos|
living_in_row << [row_index, pos] if should_live?(row_index, pos)
end
living_in_row
end
def should_live? x, y
alive_n = @neigh_gen.get_neighbours(x, y).count { |elem| elem == true }
return alive_cond?(alive_n) if @current_field[x][y] == true
dead_cond?(alive_n)
end
def alive_cond? count_alive
return false if count_alive < 2 or count_alive > 3
true
end
def dead_cond? count_alive
return true if count_alive == 3
false
end
end
class Board
include BoardEnumerable
def initialize *cells
cells_leg = produce_legitimate cells
@field = construct_field cells_leg
cells_leg.each do |x, y|
@field[x][y] = true
end
end
def [] x, y
@field[x][y] or false
end
def next_generation
gen = GenerationGenerator.new @field
gen.produce_generation
end
private
def construct_field cells
dim1 = cells.empty? ? 0 : cells.map(&:first).max
dim2 = cells.empty? ? 0 : cells.map(&:last).max
Array.new(dim1 + 2) { Array.new(dim2 + 2) { false } }
end
def produce_legitimate cells
return [] if cells == [[]] or cells == []
cells = (cells.first.first.kind_of? Array) ? cells.first : cells
end
end
end

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

........F........F

Failures:

  1) GameOfLife::Board indexing works for live and dead cells
     Failure/Error: new_board[42, 42].should be_false
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20111221-3114-11h5h5o/solution.rb:145:in `[]'
     # /tmp/d20111221-3114-11h5h5o/spec.rb:63:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) GameOfLife::Board GameOfLife::Board evolution rules keeps stable formations stable
     Failure/Error: board.count.should eq cells.count
       
       expected: 6
            got: 5
       
       (compared using ==)
     # /tmp/d20111221-3114-11h5h5o/spec.rb:172:in `expect_generation_in'
     # /tmp/d20111221-3114-11h5h5o/spec.rb:160:in `block (6 levels) in <top (required)>'
     # /tmp/d20111221-3114-11h5h5o/spec.rb:158:in `times'
     # /tmp/d20111221-3114-11h5h5o/spec.rb:158:in `block (5 levels) in <top (required)>'
     # /tmp/d20111221-3114-11h5h5o/spec.rb:155:in `each'
     # /tmp/d20111221-3114-11h5h5o/spec.rb:155:in `block (4 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.3479 seconds
18 examples, 2 failures

Failed examples:

rspec /tmp/d20111221-3114-11h5h5o/spec.rb:56 # GameOfLife::Board indexing works for live and dead cells
rspec /tmp/d20111221-3114-11h5h5o/spec.rb:151 # GameOfLife::Board GameOfLife::Board evolution rules keeps stable formations stable

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

Константин обнови решението на 19.12.2011 14:02 (преди над 8 години)

+module BoardEnumerable
+
+ include Enumerable
+
+ def each &block
+ @field.each_with_index { |elem, ind| each_yield elem, ind, &block }
+ end
+
+ def count
+ @field.flatten.count { |elem| elem == true }
+ end
+
+ private
+
+ def each_yield array, index
+ array.each_index do |pos|
+ yield index, pos if array[pos] == true
+ end
+ end
+
+end
+
+
+
+module GameOfLife
+
+class NeighbourGenerator
+
+ def initialize field
+ @field = field
+ end
+
+ def get_neighbours x, y
+ neigh = []
+ neigh << [left(x,y), right(x,y)]
+ neigh << [top(x,y), top_left(x,y), top_right(x,y)]
+ (neigh + [bottom(x,y), bottom_left(x,y), bottom_right(x,y)]).flatten
+ end
+
+ private
+
+ def left x, y
+ y < 1 ? false : @field[x][y-1]
+ end
+
+ def right x, y
+ @field[x][y+1] == nil ? false : @field[x][y+1]
+ end
+
+ def top x, y
+ x < 1 ? false : @field[x-1][y]
+ end
+
+ def top_left x, y
+ (x < 1 or y < 1) ? false : @field[x-1][y-1]
+ end
+
+ def top_right x, y
+ return false if x < 1
+ @field[x-1][y+1] == nil ? false : @field[x-1][y+1]
+ end
+
+ def bottom x, y
+ @field[x+1] == nil ? false : @field[x+1][y]
+ end
+
+ def bottom_left x, y
+ return false if @field[x+1] == nil
+ y < 1 ? false : @field[x+1][y-1]
+ end
+
+ def bottom_right x, y
+ return false if @field[x+1] == nil
+ @field[x+1][y+1] == nil ? false : @field[x+1][y+1]
+ end
+
+end
+
+
+class GenerationGenerator
+
+ def initialize past_gen_field
+ @current_field = past_gen_field
+ @neigh_gen = NeighbourGenerator.new @current_field
+ end
+
+ def produce_generation
+ Board.new produce_living
+ end
+
+ private
+
+ def count_alive array
+ array.count { |cell| cell == true }
+ end
+
+ def produce_living
+ living_arr = []
+ @current_field.each_with_index do |row, row_index|
+ living_arr += living_from_row(row, row_index)
+ end
+ living_arr
+ end
+
+ def living_from_row row, row_index
+ living_in_row = []
+ row.each_with_index do |elem, pos|
+ living_in_row << [row_index, pos] if should_live?(row_index, pos)
+ end
+ living_in_row
+ end
+
+ def should_live? x, y
+ alive_n = @neigh_gen.get_neighbours(x, y).count { |elem| elem == true }
+ return alive_cond?(alive_n) if @current_field[x][y] == true
+ dead_cond?(alive_n)
+ end
+
+ def alive_cond? count_alive
+ return false if count_alive < 2 or count_alive > 3
+ true
+ end
+
+ def dead_cond? count_alive
+ return true if count_alive == 3
+ false
+ end
+
+end
+
+
+class Board
+
+ include BoardEnumerable
+
+ def initialize *cells
+ cells_leg = produce_legitimate cells
+ @field = construct_field cells_leg
+ cells_leg.each do |x, y|
+ @field[x][y] = true
+ end
+ end
+
+ def [] x, y
+ @field[x][y] or false
+ end
+
+ def next_generation
+ gen = GenerationGenerator.new @field
+ gen.produce_generation
+ end
+
+ private
+
+ def construct_field cells
+ dim1 = cells.empty? ? 0 : cells.map(&:first).max
+ dim2 = cells.empty? ? 0 : cells.map(&:last).max
+ Array.new(dim1 + 2) { Array.new(dim2 + 2) { false } }
+ end
+
+ def produce_legitimate cells
+ return [] if cells == [[]] or cells == []
+ cells = (cells.first.first.kind_of? Array) ? cells.first : cells
+ end
+
+end
+
+end