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

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

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

Резултати

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

Код

class Integer
def prime?
return false if self < 2
upper_limit = Math.sqrt(self)
(2..upper_limit).all? { |i| remainder(i).nonzero? }
end
def prime_factor?(number)
number.prime? and remainder(number).zero?
end
def prime_factors # FIXME
factors = []
number = self.abs
while number > 1
(2..number).each do |i|
number.prime_factor? i and factors << i and number /= i
end
end
factors.sort
end
def harmonic
sum = 0
(1..self).each { |n| sum += Rational(1, n) }
sum
end
def digits
number = self.abs
digits = []
while number > 0
digits << number % 10
number /= 10
end
digits.reverse
end
end
class Array
def frequencies
frequencies = Hash.new(0)
(0...length).each do |i|
if frequencies.key?(self[i])
frequencies[self[i]] += 1
else
frequencies[self[i]] = 1
end
end
frequencies
end
def average
return if empty?
reduce(:+).fdiv(count)
end
def drop_every(n)
reduced_array = []
each_with_index do |item, i|
reduced_array << item if (i + 1).remainder(n).nonzero?
end
reduced_array
end
def combine_with(other)
combined = []
max_length = [length, other.length].max
(0...max_length).each do |i|
combined << self[i] if i < length
combined << other[i] if i < other.length
end
combined
end
end

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

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

Failures:

  1) Integer#digits constructs an array containing the digits of a number
     Failure/Error: 0.digits.should      eq [0]
       
       expected: [0]
            got: []
       
       (compared using ==)
     # /tmp/d20131023-4395-uljptz/spec.rb:44: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.04373 seconds
14 examples, 1 failure

Failed examples:

rspec /tmp/d20131023-4395-uljptz/spec.rb:43 # Integer#digits constructs an array containing the digits of a number

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

Моника обнови решението на 13.10.2013 18:00 (преди над 10 години)

+class Integer
+
+ def prime?
+ return false if self == 0 or self == 1 or self < 0
+
+ middle = Math.sqrt(self)
+ (2..middle).each do |d|
+ return false if self % d == 0
+ end
+
+ return true
+ end
+
+ def primeFactor? f
+ f.prime? and self % f == 0
+ end
+
+ def prime_factors
+ factors = []
+ self > 0 ? number = self : number = -self
+
+ while number > 1
+ (2..number).any? do |f|
+ number.primeFactor? f and factors << f and number /= f
+ end
+ end
+
+ factors.sort!
+ end
+
+ def harmonic
+ sum = 0
+ (1..self).each do |n|
+ sum += Rational(1, n)
+ end
+ sum
+ end
+
+ def digits
+ self > 0 ? number = self : number = -self
+ digits = []
+ while number > 0
+ digits << number % 10 and number /= 10
+ end
+ digits.reverse!
+ end
+
+end
+
+class Array
+
+ def frequencies
+ freqs = {}
+ (0..self.length-1).each do |i|
+ if freqs.key?(self[i])
+ freqs[self[i]] += 1
+ else
+ freqs.store(self[i], 1)
+ end
+ end
+ freqs
+ end
+
+ def average
+ return if self.empty?
+ sum = 0.0
+ count = 0
+ (0..self.length-1).each do |i|
+ sum = sum + self[i].to_i and count = count + 1
+ end
+ result = sum / count
+ end
+
+ def drop_every(n)
+ array = []
+ (0..self.length-1).each do |i|
+ array << self[i - 1] unless i % n == 0
+ end
+ array
+ end
+
+ def combine_with(other)
+ return self if other.empty?
+ return other if self.empty?
+ array = []
+ (0..[self.length-1, other.length-1].max).each do |i|
+ (array << self[i] if self[i]) and (array << other[i] if other[i])
+ end
+ array
+ end
+
+end

Моника обнови решението на 13.10.2013 18:15 (преди над 10 години)

class Integer
def prime?
return false if self == 0 or self == 1 or self < 0
middle = Math.sqrt(self)
(2..middle).each do |d|
return false if self % d == 0
end
return true
end
- def primeFactor? f
- f.prime? and self % f == 0
- end
+ def primeFactor? f
+ f.prime? and self % f == 0
+ end
def prime_factors
factors = []
- self > 0 ? number = self : number = -self
+ self > 0 ? number = self : number = -self
- while number > 1
- (2..number).any? do |f|
- number.primeFactor? f and factors << f and number /= f
- end
- end
+ while number > 1
+ (2..number).any? do |f|
+ number.primeFactor? f and factors << f and number /= f
+ end
+ end
- factors.sort!
- end
+ factors.sort!
+ end
- def harmonic
- sum = 0
- (1..self).each do |n|
- sum += Rational(1, n)
- end
- sum
- end
+ def harmonic
+ sum = 0
+ (1..self).each do |n|
+ sum += Rational(1, n)
+ end
+ sum
+ end
- def digits
- self > 0 ? number = self : number = -self
- digits = []
- while number > 0
- digits << number % 10 and number /= 10
- end
- digits.reverse!
- end
+ def digits
+ self > 0 ? number = self : number = -self
+ digits = []
+ while number > 0
+ digits << number % 10 and number /= 10
+ end
+ digits.reverse!
+ end
end
class Array
- def frequencies
- freqs = {}
- (0..self.length-1).each do |i|
- if freqs.key?(self[i])
- freqs[self[i]] += 1
- else
- freqs.store(self[i], 1)
- end
- end
- freqs
- end
+ def frequencies
+ freqs = {}
+ (0..self.length-1).each do |i|
+ if freqs.key?(self[i])
+ freqs[self[i]] += 1
+ else
+ freqs.store(self[i], 1)
+ end
+ end
+ freqs
+ end
- def average
- return if self.empty?
- sum = 0.0
- count = 0
- (0..self.length-1).each do |i|
- sum = sum + self[i].to_i and count = count + 1
- end
- result = sum / count
- end
+ def average
+ return if self.empty?
+ sum = 0.0
+ count = 0
+ (0..self.length-1).each do |i|
+ sum = sum + self[i].to_i and count = count + 1
+ end
+ result = sum / count
+ end
- def drop_every(n)
- array = []
- (0..self.length-1).each do |i|
- array << self[i - 1] unless i % n == 0
- end
- array
- end
+ def drop_every(n)
+ array = []
+ (0..self.length-1).each do |i|
+ array << self[i - 1] unless i % n == 0
+ end
+ array
+ end
- def combine_with(other)
- return self if other.empty?
- return other if self.empty?
- array = []
- (0..[self.length-1, other.length-1].max).each do |i|
- (array << self[i] if self[i]) and (array << other[i] if other[i])
- end
- array
- end
+ def combine_with(other)
+ return self if other.empty?
+ return other if self.empty?
+ array = []
+ (0..[self.length-1, other.length-1].max).each do |i|
+ (array << self[i] if self[i]) and (array << other[i] if other[i])
+ end
+ array
+ end
end

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

  • Не оставяй празен ред в началото на дефиницията на клас (ред 2 и 51), както и преди end (ред 47, 91)
  • Може да напишеш условието на ред 4 доста по-просто; помъчи се, моля :)
  • Ред 6 - middle е грешно като име; корен от нещо не е "среда"; "таван"/"лимит" на нещо, може би, но не е и среда
  • d е лошо име на променлива; такива са и f, n, freqs, array и други от сорта; съкращавайки няколко символа, не печелиш нищо, а губиш много; стреми се да спазваш clarity over brevity
  • Все още имаш проблеми със спазването на конвенциите; консултирай се с ръководството по стил; например ред 14; на ред 28 имаш проблем с идентацията
  • Пак на ред 14, си изпуснала скобите около параметъра при дефиницията на метода; по-долу в кода си дефинираш методи, като слагаш скоби около параметъра; това е неконсистентност и е по-лошо от неспазване на конвенциите
  • Предпочитаме вариантите с думи на проверката за делимост, т.е. remainder(number), zero? и nonzero?
  • В Ruby няма нужда да пишеш return, ако искаш да върнеш стойността на последно изпълнения израз в метод; това важи за ред 11, например
  • За prime? виж дали не можеш да използваш някак методите all?, any? или none?
  • Ред 20 е нещо, което никога не се прави така; или го правиш с number = self > 0 ? self : -self, или търсиш дали няма такъв вграден метод (hint: има; намери го); това важи и за ред 40
  • Ред 24 също е abomination; никога не бих очаквал в условна конструкция да се променят данни; ползвай if
  • Пак там, не разбирам защо ползваш any?; това е предикатен метод, но ти не се възползваш от върната от него стойност; ако искаш да обходиш елементите в диапазона, ползвай each; ако искаш да прекъснеш итерацията, ползвай break (ще го споменем понеделник)
  • Няма смисъл от мутиращата версия на метода sort!, която ползваш на ред 28; може да е и само sort; същото важи и за ред 45
  • Виж какво прави методът reduce и помисли къде би могла да го ползваш
  • (0..self.length-1) е по-добре да се замести с (0...self.length) на ред 54, 68, 76... А и трябва да има интервал около - тук, според стиловите конвенции
  • Виж какво прави Hash.new(0) и дали има как да го ползваш във frequencies
  • Пак там, за да сложиш нещо в хеш, не ползваш store, а []=, т.е. freqs[foo] = bar
  • Виж какво прави each_with_index и дали има как да го ползваш
  • self. се "подразбира", когато предшества извикване на метод (ще го кажем по-натам) и е излишен; в почти всички такива случаи се пропуска (напр. ред 54, 68, 76, ...)
  • На ред 77 имаш един излишен интервал м/у i %
  • За случаите като този на ред 86, извеждай си локална променлива, защото тази дефиниция на диапазон става твърде нечетима
  • За ред 87 важи същото, което казах по-горе за условия и промяна на данни - не се прави така, не се ползва and по този начин

Моника обнови решението на 15.10.2013 01:57 (преди над 10 години)

class Integer
-
def prime?
- return false if self == 0 or self == 1 or self < 0
+ return false if self < 2
- middle = Math.sqrt(self)
- (2..middle).each do |d|
- return false if self % d == 0
- end
-
- return true
+ upper_limit = Math.sqrt(self)
+ (2..upper_limit).all? { |i| remainder(i).nonzero? }
end
- def primeFactor? f
- f.prime? and self % f == 0
+ def prime_factor?(number)
+ number.prime? and remainder(number).zero?
end
- def prime_factors
+ def prime_factors # FIXME
factors = []
- self > 0 ? number = self : number = -self
-
+ number = self.abs
while number > 1
- (2..number).any? do |f|
- number.primeFactor? f and factors << f and number /= f
+ (2..number).each do |i|
+ number.prime_factor? i and factors << i and number /= i
end
end
-
- factors.sort!
+ factors.sort
end
def harmonic
sum = 0
- (1..self).each do |n|
- sum += Rational(1, n)
- end
+ (1..self).each { |n| sum += Rational(1, n) }
sum
end
def digits
- self > 0 ? number = self : number = -self
+ number = self.abs
digits = []
while number > 0
- digits << number % 10 and number /= 10
+ digits << number % 10
+ number /= 10
end
- digits.reverse!
+ digits.reverse
end
-
end
class Array
-
def frequencies
- freqs = {}
- (0..self.length-1).each do |i|
- if freqs.key?(self[i])
- freqs[self[i]] += 1
+ frequencies = Hash.new(0)
+ (0...length).each do |i|
+ if frequencies.key?(self[i])
+ frequencies[self[i]] += 1
else
- freqs.store(self[i], 1)
+ frequencies[self[i]] = 1
end
end
- freqs
+ frequencies
end
def average
- return if self.empty?
- sum = 0.0
- count = 0
- (0..self.length-1).each do |i|
- sum = sum + self[i].to_i and count = count + 1
- end
- result = sum / count
+ return if empty?
+ reduce(:+).fdiv(count)
end
def drop_every(n)
- array = []
- (0..self.length-1).each do |i|
- array << self[i - 1] unless i % n == 0
+ reduced_array = []
+ each_with_index do |item, i|
+ reduced_array << item if (i + 1).remainder(n).nonzero?
end
- array
+ reduced_array
end
def combine_with(other)
- return self if other.empty?
- return other if self.empty?
- array = []
- (0..[self.length-1, other.length-1].max).each do |i|
- (array << self[i] if self[i]) and (array << other[i] if other[i])
+ combined = []
+ max_length = [length, other.length].max
+ (0...max_length).each do |i|
+ combined << self[i] if i < length
+ combined << other[i] if i < other.length
end
- array
+ combined
end
-
end