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

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

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

Резултати

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

Код

require 'set'
module GameOfLife
class Board
include Enumerable
def initialize(*cells)
@cells = Set.new cells
end
def [](x, y)
include?([x, y])
end
def next_generation
Board.new *(alive_cells | new_cells)
end
def each
@cells.each { |cell| yield cell }
end
@private
def alive_cells
@cells.select { |cell| alive_neighbours_count(cell).between?(2, 3) }
end
def new_cells
empty_neighbour_cells.select { |cell| alive_neighbours_count(cell) == 3 }
end
def neighbours(cell)
[-1, 0, 1].repeated_permutation(2).map { |x, y| [cell[0] + x, cell[1] + y] } - [cell]
end
def alive_neighbours_count(cell)
neighbours(cell).count { |cell| include?(cell) }
end
def empty_neighbours(cell)
neighbours(cell).select { |cell| ! include?(cell) }
end
def empty_neighbour_cells
inject([]) { |neighbours, cell| neighbours | empty_neighbours(cell) }
end
end
end

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

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

Finished in 0.45513 seconds
18 examples, 0 failures

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

Славена обнови решението на 19.12.2011 00:35 (преди над 12 години)

+require 'set'
+
+module GameOfLife
+ class Board
+ include Enumerable
+
+ def initialize(*cells)
+ @cells = Set.new cells
+ end
+
+ def [](x, y)
+ include?([x, y])
+ end
+
+ def next_generation
+ Board.new *(alive_cells | new_cells)
+ end
+
+ def each
+ @cells.each { |cell| yield cell }
+ end
+
+ @private
+
+ def alive_cells
+ @cells.select { |cell| alive_neighbours_count(cell).between?(2, 3) }
+ end
+
+ def new_cells
+ empty_neighbour_cells.select { |cell| alive_neighbours_count(cell) == 3 }
+ end
+
+ def neighbours(cell)
+ [-1, 0, 1].repeated_permutation(2).map { |x, y| [cell[0] + x, cell[1] + y] } - [cell]
+ end
+
+ def alive_neighbours_count(cell)
+ neighbours(cell).count { |cell| include?(cell) }
+ end
+
+ def empty_neighbours(cell)
+ neighbours(cell).select { |cell| ! include?(cell) }
+ end
+
+ def empty_neighbour_cells
+ inject([]) { |neighbours, cell| neighbours | empty_neighbours(cell) }
+ end
+ end
+end
  • require го слагай в началото на файла, няма смисъл да е в модула GameOfLife
  • Думата neighboards ме озадачава :)
  • На места ти липсват някои интервали — не спазваш стриктно конвенцията за whitespace в Ruby и това ме кара да се чувствам некомфортно, като чета кода ти :)

Иначе, на пръв поглед, решението изглежда добре.

Вероятно най-популярната е:

Скоби се пишат във всички случаи при дефиниране или извикване на метод, освен ако:

  • Методът няма параметри или се извиква без параметри
  • Извиквате метода само с ключове/стойности на хеш и сте изпуснали {}-скобите

Пример за второто:

User.create email: 'me@example.org', name: 'Greg Bell'

Макар че втората точка, и изобщо тази конвенция за скобите при извикване, не е изкована в каменните плочи на Руби-конвенциите и зависи донякъде от проекта/авторите на даден код.

Ако нямаш други причини да пишеш по различен начин, ти предлагам да се придържаш към това.

Така като гледам промените, които си направила, си мисля, че може би не е много добре така със скобите. Примерно, аз бих изпуснал скобите в тези два случая: Set.new(cells) и Board.new(*(alive_cells | new_cells)). Другото изглежда окей. С две думи, гледай да е достатъчно четимо и да е консистентно в кода ти и ще си окей.

P.S. И ако трябва да съм честен, аз се старая да изпускам скобите доста често, когато викам функции. Просто ми изглежда по-четимо.