Решение на Шеста задача от Тони Ризов

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

Към профила на Тони Ризов

Резултати

  • 6 точки от тестове
  • 1 бонус точка
  • 7 точки общо
  • 17 успешни тест(а)
  • 1 неуспешни тест(а)

Код

module GameOfLife
class Board
include Enumerable
def initialize(*population)
@population = population
end
def [](x, y)
member? [x, y]
end
def each
@population.each { |living| yield living }
end
def neighbours(member)
x, y = member
neighbours = [[x - 1, y], [x - 1, y + 1], [x, y + 1], [x + 1, y + 1]]
neighbours + [[x + 1, y], [x + 1, y - 1], [x, y - 1], [x - 1, y - 1]]
end
def living_neighbours_count(member)
(@population & neighbours(member)).count
end
def next_generation
Board.new *(survivors + resurrected)
end
def survivors
select { |living| [2, 3].member? living_neighbours_count(living) }
end
def resurrected
dead_neighbours = []
each { |living| dead_neighbours |= neighbours(living) }
dead_neighbours -= @population
dead_neighbours.select { |neighbour| living_neighbours_count(neighbour) == 3 }
end
end
end

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

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

Failures:

  1) GameOfLife::Board GameOfLife::Board enumeration live cells count returns the number of live cells on a board
     Failure/Error: new_board([0, 0], [1, 1], [0, 0]).count.should eq 2
       
       expected: 2
            got: 3
       
       (compared using ==)
     # /tmp/d20111221-3114-7948x/spec.rb:46: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.38789 seconds
18 examples, 1 failure

Failed examples:

rspec /tmp/d20111221-3114-7948x/spec.rb:43 # GameOfLife::Board GameOfLife::Board enumeration live cells count returns the number of live cells on a board

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

Тони обнови решението на 14.12.2011 16:10 (преди над 8 години)

+module GameOfLife
+ class Board
+ include Enumerable
+
+ def initialize(*population)
+ @population = population
+ end
+
+ def [](x, y)
+ member? [x, y]
+ end
+
+ def each
+ @population.each { |living| yield living }
+ end
+
+ def neighbours(member)
+ x, y = member
+ neighbours = [[x - 1, y], [x - 1, y + 1], [x, y + 1], [x + 1, y + 1]]
+ neighbours + [[x + 1, y], [x + 1, y - 1], [x, y - 1], [x - 1, y - 1]]
+ end
+
+ def living_neighbours_count(member)
+ (@population & neighbours(member)).count
+ end
+
+ def next_generation
+ Board.new *(survivors + resurrected)
+ end
+
+ def survivors
+ select { |living| [2, 3].member? living_neighbours_count(living) }
+ end
+
+ def resurrected
+ dead_neighbours = []
+ each { |living| dead_neighbours |= neighbours(living) }
+ dead_neighbours -= @population
+ dead_neighbours.select { |neighbour| living_neighbours_count(neighbour) == 3 }
+ end
+ end
+end

Доста прилично решение, при това първи предаде такова, затова получаваш бонус точка :) Няколко дребни бележки:

  • Нещо не ми харесва записа на списъка в #neighbours, ако можеш, го пренареди :)
  • Виждам два малко по-готини начина да реализираш living_neighbours_count, опитай да го преработиш (вероятно обръщайки перспективата)
  • И resurrected бих опростил малко, смятам, че има ненужни операции

Иначе, решението ти наподобява доста на моето и вероятно ще мине почти всички тестове :)