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

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

Към профила на Веселин Николов

Резултати

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

Код

require 'set'
module GameOfLife
NeighbourDeltas = [[-1, 1], [-1, 0], [1, -1], [1, 0], [0, -1], [0, 1], [-1, -1], [1, 1]]
class Board
include Enumerable
def initialize(*aliveCells)
@aliveCells = Set.new(aliveCells)
end
def [](x, y)
@aliveCells.include?([x, y])
end
def each
@aliveCells.each { |cell| yield cell[0], cell[1] }
end
def count
@aliveCells.count
end
def next_generation
new_cells = get_all_potential_cells.select { |cell| neighbours_count(cell) == 3 }
new_cells |= @aliveCells.select { |x, y| cell_lives?([x, y]) }
Board.new(*new_cells)
end
private
def cell_lives?(cell)
[2, 3].include?(neighbours_count(cell))
end
def get_all_potential_cells
@aliveCells.inject(Set.new) { |set, cell| set | get_neighbours(cell) } .to_a
end
def get_neighbours(cell)
NeighbourDeltas.map { |delta| [delta[0] + cell[0], delta[1] + cell[1]] }
end
def neighbours_count(cell)
get_neighbours(cell).select { |cell| @aliveCells.include?(cell) } .length
end
end
end

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

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

Finished in 0.40043 seconds
18 examples, 0 failures

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

Веселин обнови решението на 18.12.2011 09:55 (преди над 12 години)

+require 'set'
+
+module GameOfLife
+
+ NeighbourDeltas = [[-1, 1], [-1, 0], [1, -1], [1, 0], [0, -1], [0, 1], [-1, -1], [1, 1]]
+
+ class Board
+ include Enumerable
+
+ def initialize(*aliveCells)
+ @aliveCells = Set.new(aliveCells)
+ end
+
+ def [](x, y)
+ @aliveCells.include?([x, y])
+ end
+
+ def each
+ @aliveCells.each { |cell| yield cell[0], cell[1] }
+ end
+
+ def count
+ @aliveCells.count
+ end
+
+ def next_generation
+ new_cells = get_all_potential_cells.select { |cell| neighbours_count(cell) == 3 }
+ new_cells |= @aliveCells.select { |x, y| cell_lives?([x, y]) }
+ Board.new(*new_cells)
+ end
+
+ private
+
+ def cell_lives?(cell)
+ [2, 3].include?(neighbours_count(cell))
+ end
+
+ def get_all_potential_cells
+ @aliveCells.inject(Set.new) { |set, cell| set | get_neighbours(cell) } .to_a
+ end
+
+ def get_neighbours(cell)
+ NeighbourDeltas.map { |delta| [delta[0] + cell[0], delta[1] + cell[1]] }
+ end
+
+ def neighbours_count(cell)
+ get_neighbours(cell).select { |cell| @aliveCells.include?(cell) } .length
+ end
+
+ end
+end

Решението изглежда прилично на пръв поглед, но имам малко забележки относно спазването на Ruby coding style-конвенциите:

  • Имена на константи, които не са модули и класове, се записват като NEIGHBOUR_DELTAS, а не NeighbourDeltas
  • Имена на методи, локални, инстанционни променливи и прочее се записват в underscore_lower_case, а не така: @aliveCells.
  • Пробвай да си кръщаваш методите без get_* отпред. Може би ще стане една идея по-четимо. Например neighbours_of(cell), вместо get_neighbours(cell).