Решение на Първа задача от Александър Петков

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

Към профила на Александър Петков

Резултати

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

Код

class SequenceMemberGenerator
def initialize(first_element, second_element)
@sequence_store = Hash.new do |sequence, index|
sequence[index] = sequence[index - 1] + sequence[index - 2]
end
@sequence_store[1] = first_element
@sequence_store[2] = second_element
end
def [](index)
@sequence_store[index]
end
end
class Fibonacci
def initialize
@@fibonacci_sequence ||= SequenceMemberGenerator.new(1, 1)
end
def [](index)
@@fibonacci_sequence[index]
end
end
class Lucas
def initialize
@@lucas_sequence ||= SequenceMemberGenerator.new(2, 1)
end
def [](index)
@@lucas_sequence[index]
end
end
class Summed
def [](index)
Fibonacci.new[index] + Lucas.new[index]
end
end
def series(name, index)
if name == 'fibonacci'
Fibonacci.new[index]
elsif name == 'lucas'
Lucas.new[index]
else
Summed.new[index]
end
end

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

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

Finished in 0.01709 seconds
12 examples, 0 failures

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

Александър обнови решението на 11.10.2014 13:12 (преди около 10 години)

+class SumOfPreviousTwoRecursiveSeries
+ def initialize(first_element, second_element)
+ @series_holder = Hash.new {
+ |hash,key| hash[key] = hash[key - 1] + hash[key - 2]
+ }
+ @series_holder[1], @series_holder[2] = first_element, second_element
+ end
+ def get_by_index(n)
+ @series_holder[n]
+ end
+end
+
+class Fibonacci
+ def get_by_index(n)
+ SumOfPreviousTwoRecursiveSeries.new(1, 1).get_by_index(n)
+ end
+end
+
+class Lucas
+ def get_by_index(n)
+ SumOfPreviousTwoRecursiveSeries.new(2, 1).get_by_index(n)
+ end
+end
+
+class Summed
+ def get_by_index(n)
+ Fibonacci.new.get_by_index(n) + Lucas.new.get_by_index(n)
+ end
+end
+
+def series(name, n)
+ Object.const_get(name.capitalize).new.get_by_index(n)
+end

Очевидно си разгледал доста неща в езика, което е супер!

  • Малко е спорно дали е overkill да използваш класове толкова грануларно. Поне по мое лично мнение. Ако ще го правиш поне се възползвай от възможността да пазиш състояние. Можеше всяка редица да има инстанционна променлива SumOfPreviousTwoRecursiveSeries и да вика нейния #get_by_index, за да не преизчисляваш два пъти едни и същи стойности. Не че настояваме за оптималност на кода, но така и така имаш гъска, защо да не снася яйца. :)
  • Object.const_get(name.capitalize).new.get_by_index(n) със сигурност обаче е overkill. Като цяло очаквахме просто решение на проста задача, отишъл си доста meta. Използвай if - elsif - else или case. Нарочно сме ви дали по 5 реда на метод. :)
  • get_by_index предполага, че има и някакви други неща, по които може да се "get"-не. В момента си в случая, в който човек би предефинирал [], разгледай как става ако още имаш хъс. :)
  • SumOfPreviousTwoRecursiveSeries може би не е най-доброто име. Да, не трябва да жертваш яснота за сметка на брой символи, но ако стане много конкретно и вербозно е време за ново име. В дадената ситуация нещо от сорта на SeriesMemberGenerator би било good enough.
  • За предпочитане е в общия случай да присвояваш на два отделни реда. По-лесно се чете. Също за едноредово присвояване Ruby създава скрити масиви.
  • Вероятно си го copy - paste-нал, но можеше да смениш със смислени имена hash и key и да поставиш разстояние след запетайката.
  • Слагай празни редове между методите.

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

Александър обнови решението на 13.10.2014 18:38 (преди около 10 години)

-class SumOfPreviousTwoRecursiveSeries
+class SeriesMemberGenerator
def initialize(first_element, second_element)
@series_holder = Hash.new {
- |hash,key| hash[key] = hash[key - 1] + hash[key - 2]
+ |series, index| series[index] = series[index - 1] + series[index - 2]
}
- @series_holder[1], @series_holder[2] = first_element, second_element
+ @series_holder[1] = first_element
+ @series_holder[2] = second_element
end
- def get_by_index(n)
- @series_holder[n]
+
+ def [](index)
+ @series_holder[index]
end
end
class Fibonacci
- def get_by_index(n)
- SumOfPreviousTwoRecursiveSeries.new(1, 1).get_by_index(n)
+ def initialize()
+ @@fibonacci_holder = SeriesMemberGenerator.new(1, 1)
end
+
+ def [](index)
+ @@fibonacci_holder[index]
+ end
end
class Lucas
- def get_by_index(n)
- SumOfPreviousTwoRecursiveSeries.new(2, 1).get_by_index(n)
+ def initialize()
+ @@lucas_holder = SeriesMemberGenerator.new(2, 1)
end
+
+ def [](index)
+ @@lucas_holder[index]
+ end
end
class Summed
- def get_by_index(n)
- Fibonacci.new.get_by_index(n) + Lucas.new.get_by_index(n)
+ def [](index)
+ Fibonacci.new[index] + Lucas.new[index]
end
end
-def series(name, n)
- Object.const_get(name.capitalize).new.get_by_index(n)
+def series(name, index)
+ if name == 'fibonacci'
+ Fibonacci.new[index]
+ elsif name == 'lucas'
+ Lucas.new[index]
+ else
+ Summed.new[index]
+ end
end
  • Не слагай скоби при дефинирането или викането на методи без аргументи (в това число и initialize).
  • Опитай се да измислиш по-добри имена от fibonacci_holder, lucas_holder и series_holder.
  • Инициализирай @@fibonacci_holder и @@lucas_holder с ||=. Така като създаваш нови инстанции няма да се refresh-ва класовата променлива, а ще се възползваш от направените изчисления.

Сори, че те карам да търсиш неща и те поправям малко повече, но това е решение, на което искам накрая да дам бонус точка. :)

Александър обнови решението на 13.10.2014 23:01 (преди около 10 години)

class SeriesMemberGenerator
def initialize(first_element, second_element)
- @series_holder = Hash.new {
- |series, index| series[index] = series[index - 1] + series[index - 2]
- }
+ @series_holder = Hash.new do |series, index|
+ series[index] = series[index - 1] + series[index - 2]
+ end
@series_holder[1] = first_element
@series_holder[2] = second_element
end
def [](index)
@series_holder[index]
end
end
class Fibonacci
def initialize()
@@fibonacci_holder = SeriesMemberGenerator.new(1, 1)
end
def [](index)
@@fibonacci_holder[index]
end
end
class Lucas
def initialize()
@@lucas_holder = SeriesMemberGenerator.new(2, 1)
end
def [](index)
@@lucas_holder[index]
end
end
class Summed
def [](index)
Fibonacci.new[index] + Lucas.new[index]
end
end
def series(name, index)
if name == 'fibonacci'
Fibonacci.new[index]
elsif name == 'lucas'
Lucas.new[index]
else
Summed.new[index]
end
end

Александър обнови решението на 14.10.2014 14:44 (преди около 10 години)

-class SeriesMemberGenerator
+class SequenceMemberGenerator
def initialize(first_element, second_element)
- @series_holder = Hash.new do |series, index|
- series[index] = series[index - 1] + series[index - 2]
+ @sequence_store = Hash.new do |sequence, index|
+ sequence[index] = sequence[index - 1] + sequence[index - 2]
end
- @series_holder[1] = first_element
- @series_holder[2] = second_element
+ @sequence_store[1] = first_element
+ @sequence_store[2] = second_element
end
def [](index)
- @series_holder[index]
+ @sequence_store[index]
end
end
class Fibonacci
- def initialize()
- @@fibonacci_holder = SeriesMemberGenerator.new(1, 1)
+ def initialize
+ @@fibonacci_sequence ||= SequenceMemberGenerator.new(1, 1)
end
def [](index)
- @@fibonacci_holder[index]
+ @@fibonacci_sequence[index]
end
end
class Lucas
- def initialize()
- @@lucas_holder = SeriesMemberGenerator.new(2, 1)
+ def initialize
+ @@lucas_sequence ||= SequenceMemberGenerator.new(2, 1)
end
def [](index)
- @@lucas_holder[index]
+ @@lucas_sequence[index]
end
end
class Summed
def [](index)
Fibonacci.new[index] + Lucas.new[index]
end
end
def series(name, index)
if name == 'fibonacci'
Fibonacci.new[index]
elsif name == 'lucas'
Lucas.new[index]
else
Summed.new[index]
end
end

Мерси, коментарите са си на място. (y) :)

Някой неща относно именуването, за които си мислех:

  • реших все пак да използвам sequence вместо series, както спомена снощи (сигурно познато).
  • sequence_lookup ми харесва повече от sequence_store, но skeptic не го разпознава като английска дума. :)
  • за SequenceMemberGenerator не се сещам как името хем да подскаже, че тези редици се генерират задължително чрез сумиране на предните два члена (което си е бая ключово), хем да не звучи като изречение. :) Но и така бива, предполагам.