Решение на Шеста задача от Георги Събев

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

Към профила на Георги Събев

Резултати

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

Код

module GameOfLife
class Board
end
end
class GameOfLife::Board
include Enumerable
def initialize *pairs
@cells = pairs.uniq
end
def [] x, y
!!@cells.index([x, y])
end
def each
@cells.each { |cell| yield cell }
end
def next_generation
survivors = select { |x, y| survive x, y }
born = map { |x, y| newborn x, y }.flatten 1
GameOfLife::Board.new *(survivors + born).uniq
end
private
def neighbours x, y, born = true
all = ([x-1, x, x+1].product [y-1, y, y+1]) - [[x, y]]
all.select { |x, y| self[x, y] == born }
end
def survive x, y
case neighbours(x, y).count
when (0..1) then false
when (2..3) then true
when (3..8) then false
end
end
def newborn x, y
unborn = neighbours x, y, false
unborn.select { |x, y| neighbours(x, y).size == 3 }
end
end

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

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

Finished in 0.44244 seconds
18 examples, 0 failures

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

Георги обнови решението на 17.12.2011 17:01 (преди над 12 години)

+module GameOfLife
+ class Board
+ end
+end
+
+class GameOfLife::Board
+ include Enumerable
+
+ def initialize *pairs
+ @cells = pairs.uniq
+ end
+
+ def [] x, y
+ !!@cells.index([x, y])
+ end
+
+ def each
+ @cells.each { |cell| yield cell }
+ end
+
+ def next_generation
+ survivors = select { |x, y| survive x, y }
+ born = map { |x, y| newborn x, y }.flatten 1
+ GameOfLife::Board.new *(survivors + born).uniq
+ end
+
+ private
+
+ def neighbours x, y, born = true
+ all = ([x-1, x, x+1].product [y-1, y, y+1]) - [[x, y]]
+ all.select { |x, y| self[x, y] == born }
+ end
+
+ def survive x, y
+ case neighbours(x, y).count
+ when (0..1) then false
+ when (2..3) then true
+ when (3..8) then false
+ end
+ end
+
+ def newborn x, y
+ unborn = neighbours x, y, false
+ unborn.select { |x, y| neighbours(x, y).size == 3 }
+ end
+end
+

Ами така кода е по-вляво. Има по-малка степен на вложеност. Няма друга причина. В интерес на истината не съм си го измислил сам, а съм го забелязвал в реални проекти в github. Така че може и да има някаква друга идея.

Изкуствено е и ако питаш мен, непопулярно. Проблемът с непопулярните неща е, че когато някой друг ги види, започва да се чуди каква е причината това да е така, а не по "стандартния" начин. Затова препоръчвам да се избягват такива непопулярни техники на писане на код. Винаги е готино човек да пробва различни неща, но когато пишеш код, който остава за поколенията, трябва да го пишеш с пет на ум... Трябва да е максимално straight-forward (без това да го прави малоумен, разбира се). Трябва да се търси подходящият баланс.

В конкретния случай, струва ми се, че само по-малката с едно ниво идентация не е достатъчно солидна причина да се излезе от традиционните релси. Но това е само мое мнение, ти имаш право да мислиш по друг начин и в крайна сметка, решението остава твое. Просто искам да знаеш какво според моя опит е по-добре в конкретната ситуация.