Методи обнови решението на 10.10.2013 11:39 (преди около 11 години)
+class Integer
+ def prime?
+ 2.upto(abs - 1).all? { |integer| abs % integer != 0 }
+ end
+
+ def prime_factors
+ 2.upto(abs).each do |x|
+ if x.prime? and abs % x == 0 and abs / x > 1
+ return [x, (abs/x).prime_factors].flatten
+ end
+ if abs / x == 1 and abs % x == 0
+ return [x]
+ end
+ end
+ end
+
+ def harmonic
+ denominator = 1.upto(abs).inject { |a,b| a * b }
+ numerator = 1.upto(abs).map { |x| denominator / x }. inject { |a, b| a + b }
+ Rational(numerator, denominator)
+ end
+
+ def digits
+ digit = abs % 10
+ if abs / 10 > 0
+ return [(abs / 10).digits, digit].flatten
+ end
+ [digit]
+ end
+end
+
+class Array
+ def frequencies
+ output = Hash.new
+ each do |x|
+ output[x] = count(x)
+ end
+ output
+ end
+
+ def average
+ inject { |a, b| a + b } / count.to_f
+ end
+
+ def drop_every(n)
+ output = []
+ each_index do |x|
+ if (x + 1) % n != 0 then output << at(x) end
+ end
+ output
+ end
+
+ def combine_with(other)
+ output = []
+ each_index do |x|
+ output << at(x)
+ output << other[x]
+ end
+ output.compact
+ end
+end
- Мисля, че може да попреработиш
#prime_factos
малко. Има повтаряща се логика и изглежда сложничко. - Стилово уточнение там:
(abs/x)
– тук трябва да има интервали около/
-
return [x, (abs/x).prime_factors].flatten
може да се запише по-просто катоreturn [x] + (abs / x).prime_factors
; подобно нещо важи и заreturn
-а в#digits
– събиране на списъци е по-проста за възприемане операция отArray#flatten
- Стил - интервал след запетаята тук:
|a,b|
(на всичкото отгоре, един ред по-надолу си сложил запетая, т.е. си неконсистентен, което е дори по-зле) - Няма нужда да ползваш
abs
в#harmonic
, по условие имаме: "Приемете, че за n <= 0, методът е недефиниран." - На ред 19 има много лошо поставен интервал тук:
. inject
- Ред 25:
abs / 10 > 0
се записва по-простичко катоabs >= 10
:) Не виждам причина да делиш, за да направиш тази проверка - Ред 34, още не сме го казали, но
Hash.new
без никакви аргументи не се ползва; използва се литералният синтаксис:{}
- Ползвай
size
илиlength
ако искаш просто бройката елементи в списък, недей да ползвашcount
за целта, понеже той прави повечко неща (както си видял вече) - Ред 49 си плаче за postfix-ен
if
, т.е.:output << at(x) if (x + 1) % n != 0
- Пак на същото място, виж дали няма някакви методи на целите числа, които да ти връщат предишно/следващо число
- Потърси документацията на
each_with_index
и виж дали може да ти е полезен някак - Като цяло, предпочитаме комбинации (вериги, chain-вания) от
map
+select
/reject
и т.н., отколкото това пълнене на резултат вoutput
-
output
е недостатъчно добро име на променлива; твърде общо е; ползваш го навсякъде и това не е добър вариант; затова виж предния съвет, който ще те спаси от нуждата да имаш такава локална променлива, или поне прави усилието да я кръстиш по-ясно; например, вcombine_with
, може да бъдеcombined_elements
и т.н. - Операторът
<<
(или още, методътArray#<<
) може да се chain-ва, защото връща масива (виж му документацията); иде реч за редове 56 и 57
Спирам дотук, че станаха доста неща. Като цяло, си на прав път и се справяш прилично добре за първо решение на първа задача :) А и си първият предал решение, така че ще ти дам бонус точка след оценяването (ако не забравя :P)