Антонио обнови решението на 13.10.2013 02:07 (преди около 12 години)
+class Integer
+ def prime?
+ return p false if self < 1
+ (2..self / 2).select { |x| return p false if self % x == 0 }
+ return p true
+ end
+
+ def prime_factors
+ count, primes, number = 2, [], self
+ until number.abs == 1
+ primes.push count if number % count == 0
+ if number % count == 0 then number /= count else count += 1 end
+ end
+ return p primes
+ end
+
+ def harmonic
+ return p nil if self <= 0
+ sum_n = Rational(0, 1)
+ (1..self).select { |x| sum_n += Rational(1, x) }
+ return p sum_n
+ end
+
+ def digits
+ number, arr_d = self.abs, []
+ until number == 0
+ arr_d << number % 10
+ number /= 10
+ end
+ return p arr_d.reverse
+ end
+end
+
+class Array
+ def frequencies_help(x)
+ count = 0
+ self.each { |y| count += 1 if x == y }
+ return count
+ end
+
+ def frequencies
+ frc_elem = Hash.new
+ self.each do |x|
+ frc_elem[x] = self.frequencies_help(x) if frc_elem[x] == nil
+ end
+ return p frc_elem
+ end
+
+ def average
+ return p nil if self.empty?
+ sum = 0.0
+ self.each { |x| sum += x }
+ return p sum / self.size
+ end
+
+ def drop_every(n)
+ count, no_n_elem = 0, []
+ self.each do |x|
+ count += 1
+ if count == n then count = 0 else no_n_elem << x end
+ end
+ return p no_n_elem
+ end
+
+ def combine_with(other)
+ shrt = if self.size <= other.size then self.size else other.size end
+ arr = []
+ (0..shrt - 1).select { |x| arr << self[x] & arr << other[x] }
+ (shrt..other.size - 1).select { |x| arr << other[x] } if shrt < other.size
+ (shrt..self.size - 1).select { |x| arr << self[x] } if shrt < self.size
+ return p arr
+ end
+end
Ето малко бележки:
- Идентацията ти е омазана; консултирай се с ръководството по стил и си я оправи, иначе рискуваш да ти вземем точки
- В Ruby няма нужда да пишеш
return, ако искаш да върнеш стойността на последно изпълнения израз в метод; това важи за редове 5, 14, 21 и други - Това
pвreturn-изразите ти е излишно, трябва да го махнеш - Виж какво правят методите
any?/all?/none?и дали можеш да ги ползваш по някакъв начин вprime? - Предпочитай
Array#<<, вместоArray#push(ред 11) - Предпочитаме вариантите с думи на проверката за делимост, т.е.
remainder(number)и методитеzero?иnonzero? - На ред 12, не ползвай
if/then/elseпо този начин, четимостта се нарушава - На ред 18, пак не трябва да има
pтам, а иnilе излишно; достатъчно щеше да е самоreturn if self <= 0 - Защо
sum_n?sumе достатъчно - Ред 20 - в случая, употребата ти на
selectе неправилна; искаш да ползвашeachтук, за да обходиш елементите на областта;selectправи друго - За този метод, виж какво прави
reduceи дали можеш да го ползваш по някакъв начин -
self.се "подразбира", когато предшества извикване на метод (ще го кажем по-натам) и е излишен; в почти всички такива случаи се пропуска (напр. ред 25, 37, 43, 50...) -
arr_dе много лошо име, такива са иfrc_elem,shrt,arr...; съкращавайки няколко символа, не печелиш нищо, а губиш много; спазвай clarity over brevity; тук вместоarr_dможе да ползваш спокойно иdigits, няма да има проблем - Името
frequencies_helpе лошо;occurrances_count_of(element)щеше да е по-добро; но най-добре ще е да видиш дали няма вече такъв метод (търси вEnumerable; всекиArrayги има тези методи) - Допълнително,
xиyса кофти имена в този контекст; това не е формула и тези не са неизвестни - Никога не създавай хеш с
Hash.new, ако няма да подаваш аргументи на конструктора; има си литерален синтаксис, който е{}(ред 42) - Ред 50 е излишен, няма да викаме
averageна празни списъци; иначе, пак не трябва да имаpтам, а иnilе излишно; достатъчно щеше да е самоreturn if empty? - За този метод,
reduceпак може да ти помогне -
no_n_elem? Лошо име, да.remaining_elementsе по-добро - За
drop_every, разгледай отново методите наEnumerable(всеки списък ги има); там има неща катоeach_with_index, например, които може да са ти полезни
