Марио обнови решението на 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