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

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

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

Резултати

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

Код

class Array
def to_hash()
hash = Hash[*self.flatten]
hash.default = 0
hash
end
def index_by()
values = []
self.each do |n|
values << (yield n)
end
values.zip(self).to_hash
end
def subarray_count(subarray)
subarray_count = 0
i = 0
while i < self.length
j = 0
while j < subarray.length and self.at(i) == subarray.at(j)
i+=1
j+=1
end
if j == subarray.length
subarray_count += 1
end
i -= j-1
end
subarray_count
end
def occurences_count()
tokens = []
result = []
self.each do |n|
if not tokens.include?(n)
tokens << n
end
end
tokens.each do |x|
occurences = 0
self.each do |y|
if x == y
occurences += 1
end
result << x
result << occurences
end
end
result.to_hash
end
end

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

..F..............

Failures:

  1) Array#to_hash works when the keys and values are arrays
     Failure/Error: [[1, [2, 3]], [[4, 5], 6]].to_hash.should eq(1 => [2, 3], [4, 5] => 6)
       
       expected {1=>[2, 3], [4, 5]=>6}
            got {1=>2, 3=>4, 5=>6}
       
       (compared using ==)
       
       Diff:
       @@ -1,2 +1,2 @@
       -{1=>[2, 3], [4, 5]=>6}
       +{1=>2, 3=>4, 5=>6}
     # /tmp/d20111025-2903-ylm74m/spec.rb:11:in `block (2 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.01509 seconds
17 examples, 1 failure

Failed examples:

rspec /tmp/d20111025-2903-ylm74m/spec.rb:10 # Array#to_hash works when the keys and values are arrays

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

Мартин обнови решението на 22.10.2011 21:49 (преди около 13 години)

+class Array
+ def to_hash()
+ hash = Hash[*self.flatten]
+ hash.default = 0
+ hash
+ end
+
+ def index_by()
+ values = []
+ self.each do |n|
+ values << (yield n)
+ end
+ values.zip(self).to_hash
+ end
+
+ def subarray_count(subarray)
+ subarray_count = 0
+ i = 0
+ while i < self.length
+ j = 0
+ while j < subarray.length and self.at(i) == subarray.at(j)
+ i+=1
+ j+=1
+ end
+ if j == subarray.length
+ subarray_count += 1
+ end
+ i -= j-1
+ end
+ subarray_count
+ end
+
+ def occurences_count()
+ tokens = []
+ result = []
+ self.each do |n|
+ if not tokens.include?(n)
+ tokens << n
+ end
+ end
+ tokens.each do |x|
+ occurences = 0
+ self.each do |y|
+ if x == y
+ occurences += 1
+ end
+ result << x
+ result << occurences
+ end
+ end
+ result.to_hash
+ end
+end

Георги, надявам се, че не се е*аваш с автора :)

Ето малко коментари и от мен:

  • Както вече си разбрал, Array#flatten не върши работа за #to_hash
  • В Ruby се идентира с 2 интервала; не с 4 интервала или табове с "ширина 2"
  • hash.default = 0 е криптично и странно; странните и изненадващи неща не са препоръчителни за екипна работа; по-добре Hash.new(0), защото е идиоматично за целта
  • Няма нужда от експлицитно указан self в случаите на викане на метод, напр.: self.each do ... е по-добре само като each do ...
  • Скобите в случаи като този: values << (yield n) се поставят така: values << yield(n); в твоя вариант викаш "метода" yield без скоби, но си уградил целия израз в скоби, понеже интерпретаторът ти се е оплакал; в тези случаи най-добре е да си сложиш скобите около изивкването на функцията (в случая, yield)
  • Скоби около извикване/деклариране на метод без аргументи почти винаги се изпускат; напр.: def to_hash() е по-четимо като def to_hash
  • Два вложени while-a, i, j... Прекалено сложно :) Винаги ползвай each за Enumerable неща, понеже, отново, е идиоматично; виж реализацията на този метод при Стефан, например
  • if not something е по-четимо като unless somethig; само че не ползвай unless, ако ти трябва else-клон на логиката
  • Спокойно може да пишеш код от вида: result << x << occurences; причината е, че методът << връща обекта, над който е извикан и всъщност този израз е еквивалентен на: result.<<(x).<<(occurences)