Велина обнови решението на 18.12.2011 11:24 (преди около 13 години)
+module GameOfLife
+ class Board
+ include Enumerable
+
+ NEIGHBOURS = [[-1, 0], [1, 0], [-1, 1], [0, 1], [1, 1], [-1, -1], [0, -1], [1, -1]]
+
+ attr_accessor :population
+
+ def initialize(*alive_cells)
+ @population = alive_cells.uniq
+ end
+
+ def [](*indexes)
+ if indexes.count == 2
+ population.include? indexes
+ end
+ end
+
+ def next_generation
+ next_population = []
+ next_population += alive_cells
+ next_population += born_cells
+ Board.new *next_population
+ end
+
+ def each
+ population.each { |cell| yield cell }
+ end
+
+ private
+
+ def alive_cells
+ alive_cells = []
+ population.each do |cell|
+ alive_cells << cell if (2..3).include? number_of_neighbours_alive cell
+ end
+ alive_cells
+ end
+
+ def born_cells
+ all_neighbours = []
+ population.each do |cell|
+ NEIGHBOURS.each { |x, y| all_neighbours << [cell[0] + x, cell[1] + y] }
+ end
+ all_neighbours.group_by{ |c| c }.reject{ |k, g| g.length != 3 }.map{ |k, g| k }
+ end
+
+ def number_of_neighbours_alive(cell)
+ NEIGHBOURS.count { |x, y| population.include? [cell[0] + x, cell[1] + y] }
+ end
+ end
+end
Доста добро решение, браво! Някак си ми беше приятно да го прочета този код. Няколко дребни препоръки само:
- Получаваш
count
наготово отEnumerable
, не е нуждо да го дефинираш, особено ако не ти е критично важна скоростта. - Бих се опитал да рефакторирам/премахна
cells_with_three_alive_neighbours
, не ми е в тон с останалия код, който клони към прекрасен :) - Относно
number_of_neighbours_alive
, напрво връщайNEIGHBOURS.count do |x, y| ... end
. Виж Enumerable#count за повече инфо.
Благодаря за положителния коментар и за забележките разбира се :) Взех ги под внимание и качих ново решение.. може би сега изглежда малко по-добре.