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

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

Към профила на Марио Даскалов

Резултати

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

Код

class Integer
def prime?
return false if self <= 1
(2...self).all? { |divisor| remainder(divisor).nonzero? }
end
def prime_factors
number = abs
if number.prime?
[number]
else
divisor = (2...number).find { |i| number.remainder(i).zero? }
[divisor] + (number / divisor).prime_factors
end
end
def harmonic
(1..self).inject(0.to_r) do |harmonic_sum, n|
harmonic_sum += Rational(1, n)
end
end
def digits
abs.to_s.chars.map(&:to_i)
end
end
class Array
def frequencies
frequinces = Hash.new { |hash, key| hash[key] = 0 }
each { |n| frequinces[n] += 1 }
frequinces
end
def average
reduce(0.0, :+) / size
end
def drop_every(n)
filtered_list = []
each_with_index do |item, index|
filtered_list << item unless (index + 1).remainder(n).zero?
end
filtered_list
end
def combine_with(other)
combined_list = []
max_index = self.size > other.size ? self.size : other.size
(0...max_index).each do |n|
combined_list << self[n] if self[n]
combined_list << other[n] if other[n]
end
combined_list
end
end

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

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

Failures:

  1) Array#combine_with combines two arrays by alternatingly taking elements
     Failure/Error: [:a, :b, :c].combine_with([1, nil, 3]).should       eq [:a, 1, :b, nil, :c, 3]
       
       expected: [:a, 1, :b, nil, :c, 3]
            got: [:a, 1, :b, :c, 3]
       
       (compared using ==)
     # /tmp/d20131023-4395-yzkwjy/spec.rb:110:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.01846 seconds
14 examples, 1 failure

Failed examples:

rspec /tmp/d20131023-4395-yzkwjy/spec.rb:103 # Array#combine_with combines two arrays by alternatingly taking elements

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

Марио обнови решението на 11.10.2013 21:41 (преди около 11 години)

+class Integer
+
+ def prime?
+ return false if self == 1 or self <= 0
+ divider = 2
+
+ while divider*divider <= self do
+ return false if self % divider == 0
+ divider += 1
+ end
+
+ true
+ end
+
+ def prime_factors
+ number = self > 0 ? self : -self
+ prime_factors_list = number.prime? ? [number] : []
+
+ (2...number).each do |n|
+ return [n] + (number / n).prime_factors if number % n == 0
+ end
+
+ prime_factors_list
+ end
+
+ def harmonic
+ harmonic_number = 0.to_r
+
+ (1..self).each do |n|
+ harmonic_number += Rational(1, n)
+ end
+
+ harmonic_number
+ end
+
+ def digits
+ number = self >= 0 ? self : -self
+ digits_list = self == 0 ? [0] : []
+
+ while number > 0 do
+ digits_list << number % 10
+ number /= 10
+ end
+
+ digits_list.reverse
+ end
+
+end
+
+class Array
+
+ def frequencies
+ freq_hash = {}
+
+ self.each do |n|
+ if freq_hash[n]
+ freq_hash[n] += 1
+ else
+ freq_hash[n] = 1
+ end
+ end
+
+ freq_hash
+ end
+
+ def average
+ total = 0.0
+ self.each { |n| total += n }
+ total / size
+ end
+
+ def drop_every(n)
+ drop_list = []
+
+ (0...size).each do |i|
+ drop_list << self[i] unless (i + 1) % n == 0
+ end
+
+ drop_list
+ end
+
+ def combine_with(other)
+ combined_list = []
+ max_index = self.size > other.size ? self.size : other.size
+
+ (0...max_index).each do |n|
+ combined_list << self[n] if self[n]
+ combined_list<< other[n] if other[n]
+ end
+
+ combined_list
+ end
+
+end

Ето малко бележки:

  • Ред 2 и ред 51 - не оставяй празни редове след началото на дефиницията на клас; същото важи и за редове 47 и 93 -- не се оставя празен ред преди end
  • Ред 7 - трябва да има интервали около *
  • На същия ред, do не се слага там и е ненужно; махни го
  • Предпочитаме вариантите с думи на проверката за делимост, т.е. remainder(number) и методите zero? и nonzero?
  • divider означава "разделител"; може би имаш предвид divisor, за "делител"?
  • Потърси какво правят методите any? и all? и как може да ги извикваш; ще ти позволят да направиш това, което правиш в prime? по-елегантно и в стила на Ruby
  • Ред 16 - потърси какви методи има дефинирани в Numeric и виж дали няма нещо, което да ползваш наготово
  • Този return на ред 20 ти променя логиката доста; връща директно от метода prime_factors, а не от блока, подаден на each; така, например, кодът на ред 23 няма да бъде достигнат
  • Относно harmonic, виж какво прави методът reduce и дали не можеш да го ползваш някак
  • Вместо self == 0, пробвай self.zero?, или дори само zero?
  • freq_hash е кофти име; съкращавайки няколко символа, не печелиш нищо, а губиш много; спазвай clarity over brevity; допълнително, няма никакъв проблем да имаш променлива, която се казва frequencies тук
  • self. се "подразбира" (ще го кажем по-натам) и е излишен (ред 55, ред 68 и т.н.)
  • Hash.new е конструкторът на класа за хеш; той може да бъде викан и с разни аргументи; виж му документацията и виж дали няма нещо интересно, което може да ползваш там
  • Силно препоръчвам и да разгледаш документацията на Enumerable - там е златна мина :)
  • total не е достатъчно добро име; по-добре го кръсти sum; а най-добре виж как би могъл да ползваш методите на Enumerable за целта (hint - показвали сме на лекции метода, който имам предвид, макар и да не сме го обсъждали в детайли)
  • drop_list също не е добро име; аз го разбирам малко като "kill list" и определено не очаквам да съдържа неща, които трябва да останат :)
  • Ред 76, скобите в условието са излишни, махни ги; това условие може да се запише и като ... unless remainder(i + 1).zero?
  • Ред 84, max_index е лошо име; подвежда; по-добре да е max_size; виж какво прави и Array#max
  • Има нужда от интервал преди << на ред 88

Марио обнови решението на 14.10.2013 15:38 (преди около 11 години)

class Integer
-
def prime?
return false if self == 1 or self <= 0
- divider = 2
-
- while divider*divider <= self do
- return false if self % divider == 0
- divider += 1
- end
-
- true
+ (2...self).all? { |divisor| remainder(divisor).nonzero? }
end
def prime_factors
- number = self > 0 ? self : -self
+ number = abs
prime_factors_list = number.prime? ? [number] : []
(2...number).each do |n|
- return [n] + (number / n).prime_factors if number % n == 0
+ return [n] + (number / n).prime_factors if number.remainder(n).zero?
end
prime_factors_list
end
def harmonic
- harmonic_number = 0.to_r
-
- (1..self).each do |n|
- harmonic_number += Rational(1, n)
+ (1..self).inject(0.to_r) do |harmonic_sum, n|
+ harmonic_sum += Rational(1, n)
end
-
- harmonic_number
end
def digits
- number = self >= 0 ? self : -self
- digits_list = self == 0 ? [0] : []
-
- while number > 0 do
- digits_list << number % 10
- number /= 10
- end
-
- digits_list.reverse
+ digits = []
+ abs.to_s.each_char { |n| digits << n.to_i }
+ digits
end
-
end
class Array
-
def frequencies
- freq_hash = {}
-
- self.each do |n|
- if freq_hash[n]
- freq_hash[n] += 1
- else
- freq_hash[n] = 1
- end
- end
-
- freq_hash
+ frequinces = Hash.new { |hash, key| hash[key] = 0 }
+ each { |n| frequinces[n] += 1 }
+ frequinces
end
def average
- total = 0.0
- self.each { |n| total += n }
- total / size
+ reduce(0.0, :+) / size
end
def drop_every(n)
- drop_list = []
-
- (0...size).each do |i|
- drop_list << self[i] unless (i + 1) % n == 0
+ filtered_list = []
+ each_with_index do |item, index|
+ filtered_list << item unless (index + 1).remainder(n).zero?
end
-
- drop_list
+ filtered_list
end
def combine_with(other)
combined_list = []
max_index = self.size > other.size ? self.size : other.size
(0...max_index).each do |n|
combined_list << self[n] if self[n]
- combined_list<< other[n] if other[n]
+ combined_list << other[n] if other[n]
end
combined_list
end
-
end

Марио обнови решението на 15.10.2013 16:43 (преди около 11 години)

class Integer
def prime?
- return false if self == 1 or self <= 0
+ return false if self <= 1
(2...self).all? { |divisor| remainder(divisor).nonzero? }
end
def prime_factors
number = abs
- prime_factors_list = number.prime? ? [number] : []
-
- (2...number).each do |n|
- return [n] + (number / n).prime_factors if number.remainder(n).zero?
+ if number.prime?
+ [number]
+ else
+ divisor = (2...number).find { |i| number.remainder(i).zero? }
+ [divisor] + (number / divisor).prime_factors
end
-
- prime_factors_list
end
def harmonic
(1..self).inject(0.to_r) do |harmonic_sum, n|
harmonic_sum += Rational(1, n)
end
end
def digits
- digits = []
- abs.to_s.each_char { |n| digits << n.to_i }
- digits
+ abs.to_s.chars.map(&:to_i)
end
end
class Array
def frequencies
frequinces = Hash.new { |hash, key| hash[key] = 0 }
each { |n| frequinces[n] += 1 }
frequinces
end
def average
reduce(0.0, :+) / size
end
def drop_every(n)
filtered_list = []
each_with_index do |item, index|
filtered_list << item unless (index + 1).remainder(n).zero?
end
filtered_list
end
def combine_with(other)
combined_list = []
max_index = self.size > other.size ? self.size : other.size
(0...max_index).each do |n|
combined_list << self[n] if self[n]
combined_list << other[n] if other[n]
end
combined_list
end
end