Решение на Първа задача от Камелия Пандаклиева

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

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

Резултати

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

Код

class Integer
def prime?
(2..(Math.sqrt self)).all? do |divisor|
% divisor != 0
end
end
def prime_divisors
number = abs
result = []
(2..number).step do |divisor|
if number % divisor == 0 && divisor.prime?
result << divisor
end
end
result
end
end
class Range
def fizzbuzz
result = to_a
result.map! do |item|
if item % 3 == 0
item = item % 5 == 0 ? :fizzbuzz : :fizz
else
item = item % 5 == 0 ? :buzz : item
end
end
result
end
end
class Hash
def group_values
result = Hash.new
self.each do |key, value|
if result.has_key? value
result[value] = result[value] << key
else
result.store value, [key]
end
end
result
end
end
class Array
def densities
map { |item| self.count item }
end
end

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

FF......

Failures:

  1) Integer#prime_divisors can partition a simple number
     Failure/Error: 10.prime_divisors.should eq [2, 5]
       
       expected: [2, 5]
            got: [2, 5, 10]
       
       (compared using ==)
     # /tmp/d20130307-6960-o8z6xp/spec.rb:3: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)>'

  2) Integer#prime_divisors works with negative numbers
     Failure/Error: (-10).prime_divisors.should eq [2, 5]
       
       expected: [2, 5]
            got: [2, 5, 10]
       
       (compared using ==)
     # /tmp/d20130307-6960-o8z6xp/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.00759 seconds
8 examples, 2 failures

Failed examples:

rspec /tmp/d20130307-6960-o8z6xp/spec.rb:2 # Integer#prime_divisors can partition a simple number
rspec /tmp/d20130307-6960-o8z6xp/spec.rb:10 # Integer#prime_divisors works with negative numbers

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

Камелия обнови решението на 14.10.2012 12:37 (преди над 11 години)

+class Integer
+ def prime?
+ d = 2
+ while d <= (Math.sqrt self) do
+ return false if self % d == 0
+ d += 1
+ end
+ true
+ end
+
+ def prime_divisors
+ number = self > 0 ? self : -1 * self
+ result = []
+ (2..number).step do |d|
+ result << d if number % d == 0 && d.prime?
+ end
+ result
+ end
+end
+
+class Range
+ def fizzbuzz
+ result = self.to_a
+ result.each_index do |i|
+ tree = (result[i] % 3) == 0 ? true : false
+ five = (result[i] % 5) == 0 ? true : false
+ next unless tree or five
+ if tree
+ result[i] = five ? :fizzbuzz : :fizz
+ else
+ result[i] = :buzz
+ end
+ end
+ result
+ end
+end
+
+class Hash
+ def group_values
+ result = Hash.new
+ self.each do |key, value|
+ if result.has_key? value
+ result[value] = result[value] << key
+ else
+ result.store value, [key]
+ end
+ end
+ result
+ end
+end
+
+class Array
+ def densities
+ map { |item| self.count item }
+ end
+end
  • Изпускай self., в твоя случай никъде не е нужно и обикновено се изпуска в тези ситуации
  • Методът prime? е написан на C, но с Ruby синтаксис. Трябва да бягаш от този начин на мислене... :) Освен това, обърни внимание как смяташ корен от self след всяка итерация (тъй като след всяка итерация се оценява условието на while). d не е много добро име на променлива. За упражнението, пробвай да го напишеш с any?, all?, Range или нещо от сорта.
  • Ред 12: има метод abs... Това важи за повечето неща в Ruby, има методи за много работи.
  • Методът ти fizzbuzz е подобен на prime?; виж дали можеш да го пренапишеш с map.
  • Това е redundant: (result[i] % 5) == 0 ? true : false; самият израз (забележи, че няма нужда и от скоби и се изпускат в случая) си връща булева стойност true или false: result[i] % 5 == 0. Същото важи и за другия на ред 25. Още повече, тези неща обикновено се слагат в if-а, не се изважтат в променливи. Условието не е толкова сложно, че да го изисква.

Информативно, прочети това: http://37signals.com/svn/posts/3250-clarity-over-brevity-in-variable-and-method-names

И последно, за group_values има една типична конструкция, нещо от типа на:

group_values[value] ||= []
group_values[value] << key

Камелия обнови решението на 15.10.2012 09:59 (преди над 11 години)

class Integer
def prime?
- d = 2
- while d <= (Math.sqrt self) do
- return false if self % d == 0
- d += 1
+ (2..(Math.sqrt self)).all? do |divisor|
+ % divisor != 0
end
- true
end
def prime_divisors
- number = self > 0 ? self : -1 * self
+ number = abs
result = []
- (2..number).step do |d|
- result << d if number % d == 0 && d.prime?
+ (2..number).step do |divisor|
+ if number % divisor == 0 && divisor.prime?
+ result << divisor
+ end
end
result
end
end
class Range
def fizzbuzz
- result = self.to_a
- result.each_index do |i|
- tree = (result[i] % 3) == 0 ? true : false
- five = (result[i] % 5) == 0 ? true : false
- next unless tree or five
- if tree
- result[i] = five ? :fizzbuzz : :fizz
+ result = to_a
+ result.map! do |item|
+ if item % 3 == 0
+ item = item % 5 == 0 ? :fizzbuzz : :fizz
else
- result[i] = :buzz
+ item = item % 5 == 0 ? :buzz : item
end
end
result
end
end
class Hash
def group_values
result = Hash.new
self.each do |key, value|
if result.has_key? value
result[value] = result[value] << key
else
result.store value, [key]
end
end
result
end
end
class Array
def densities
map { |item| self.count item }
end
end

Супер. Малки бележки:

  • (2..(Math.sqrt self)).all? ... обикновено се записва по-скоро така: (2..Math.sqrt(self)).all? ...
  • На 4-ти ред може и да не изпускаш self; доста е странно % divisor в нищото; въпреки, че е същото като self.%(divisor), все пак е синтактично записано като оператор и в този конкретен случай изпускането на self само обърква; т.е. self % divisor
  • Във fizzbuzz result не ти трябва изобщо, пробвай да се отървеш от него :)

Иначе другото е прилично :)

Съмнявам се. С кое Ruby си?

Проблема е, че не можеш да изпълняваш оператор както правиш на четвърти ред. Кодът е self % divisor. Пробвай да изпълниш друг оператор така (например **) и виж какво ще стане. В твоя случай, ти ползваш литерал за низ като %{divisor}. Разделителя, обаче, може да бъде каквото и да е, включително и интервал (вместо {). Затова и highlighting-а е такъв.

Кодът ти на четвърти ред съответно е 'divisor' != 0, което винаги е true. Съответно, Integer#prime? връща истина винаги.