Решение на Първа задача от Цветан Иванов

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

Към профила на Цветан Иванов

Резултати

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

Код

class Integer
def prime?
return false if self < 2
2.upto(Math.sqrt(abs)).all? { |number| abs % number != 0 }
end
def prime_factors
find_prime_factors([], 2, self)
end
def find_prime_factors(list_of_divisors, current_divisor, current_number)
while current_divisor <= abs
if current_divisor.prime? and current_number % current_divisor == 0
list_of_divisors << current_divisor
current_number = current_number / current_divisor
else
current_divisor += 1
end
end
list_of_divisors
end
def harmonic
return if self <= 0
(1..self).map { |e| 1 / e.to_r }.reduce(:+)
end
def digits
abs.to_s.chars.map { |e| e.to_i }
end
end
class Array
def average
return if empty?
reduce(0.0, :+) / length
end
def drop_every(n)
result = []
each_index { |index| result << self[index] if (index + 1) % n != 0 }
result
end
def frequencies
occurrences = Hash.new(0)
each { |number| occurrences[number] += 1 }
occurrences
end
def combine_with(other_list)
smallest_length = other_list.length < length ? other_list.length : length
combined_list = []
(0..smallest_length - 1).each do |number|
combined_list << self[number] << other_list[number]
end
combined_list << other_list.drop(smallest_length) << drop(smallest_length)
combined_list.flatten
end
end

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

..............

Finished in 0.0444 seconds
14 examples, 0 failures

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

Цветан обнови решението на 13.10.2013 14:05 (преди над 10 години)

+class Integer
+ def prime?
+ return false if self < 2
+ numbers = 2.upto(Math.sqrt(abs))
+ numbers.all? do |number|
+ abs % number != 0
+ end
+ end
+
+ def prime_factors
+ find_prime_factors([], 2, self)
+ end
+
+ def find_prime_factors(list_of_dividers, current_divider, current_number)
+ while current_divider <= abs
+ if current_divider.prime? and current_number % current_divider == 0
+ list_of_dividers << current_divider
+ current_number = current_number / current_divider
+ else
+ current_divider = current_divider + 1
+ end
+ end
+
+ list_of_dividers
+ end
+
+ def harmonic
+ return nil if self <= 0
+ result = Rational(1, 1)
+ (2..self).each do |number|
+ result = result + Rational(1, number)
+ end
+
+ result
+ end
+
+ def digits
+ abs.to_s.split('').map { |e| Integer(e) }
+ end
+end
+
+class Array
+ def average
+ return nil if empty?
+ result = 0.0
+ each { |e| result = result + e }
+
+ result / length
+ end
+
+ def drop_every(n)
+ result = []
+ each_index do |index|
+ result << self[index] if (index + 1) % n != 0
+ end
+
+ result
+ end
+
+ def frequencies
+ occurences = {}
+ each do |number|
+ if occurences.has_key?(number)
+ occurences[number] = occurences[number] + 1
+ else
+ occurences[number] = 1
+ end
+ end
+
+ occurences
+ end
+
+ def combine_with(other_list)
+ smallest_length = other_list.length < length ? other_list.length : length
+ result = []
+ (0..smallest_length - 1).each do |number|
+ result << self[number] << other_list[number]
+ end
+ adding_remaining_elements(smallest_length, other_list, result)
+
+ result
+ end
+
+ def adding_remaining_elements(smallest_length, other_list, result)
+ if smallest_length == length
+ other_list[smallest_length..other_list.length - 1].each{ |x| result << x }
+ else
+ self[smallest_length..length - 1].each{|x| result << x}
+ end
+ end
+end

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

  • В твоя случай на употреба на all? (ред 5), е по-добре да е на един ред, достатъчно четимо ще е
  • Там, numbers не ми харесва като име; това е limit или нещо от сорта
  • Виждам, че си решил prime_factors малко в стил Lisp/Scheme :) Това ме е точно Руби стил, но имената ти са прилични, с малки изключения – dividers означава "разделители"; може би имаш предвид divisors? :)
  • Red 20 - може да ползваш += там
  • Предпочитаме вариантите с думи на проверката за делимост, т.е. remainder(number), zero? и nonzero?
  • return nil if self <= 0 може да се запише и като return if self <= 0
  • За harmonic виж дали reduce няма да ти свърши работа по някакъв начин; същото важи и за average
  • Ред 38 - вж. Stirng#chars и String#to_i
  • Имаш typo в occurences (изпуснал си едно r)
  • За frequencies, виж конструктора на Hash и виж дали няма да ти свърши работа някоя негова алтернативна версия
  • result не е добро име; дали ще бъде remaining_elements (ред 52) или combined_elements, или само combined - това е по-добре от result
  • adding_remaining_elements не е кръстено правилно; трябва да е поне add_remaining_elements
  • Още повече, този метод си го извел заради skeptic; това не го одобрявам, опитай да пренапишеш combine_with така, че да няма нужда от това; разгледай методите на Array и на Enumerable (вторите ги има във всеки Array), може някои от тях да са ти полезни

Цветан обнови решението на 14.10.2013 11:20 (преди над 10 години)

class Integer
def prime?
return false if self < 2
- numbers = 2.upto(Math.sqrt(abs))
- numbers.all? do |number|
- abs % number != 0
- end
+ 2.upto(Math.sqrt(abs)).all? { |number| abs % number != 0 }
end
def prime_factors
find_prime_factors([], 2, self)
end
- def find_prime_factors(list_of_dividers, current_divider, current_number)
- while current_divider <= abs
- if current_divider.prime? and current_number % current_divider == 0
- list_of_dividers << current_divider
- current_number = current_number / current_divider
+ def find_prime_factors(list_of_divisors, current_divisor, current_number)
+ while current_divisor <= abs
+ if current_divisor.prime? and current_number % current_divisor == 0
+ list_of_divisors << current_divisor
+ current_number = current_number / current_divisor
else
- current_divider = current_divider + 1
+ current_divisor += 1
end
end
- list_of_dividers
+ list_of_divisors
end
def harmonic
- return nil if self <= 0
- result = Rational(1, 1)
- (2..self).each do |number|
- result = result + Rational(1, number)
- end
-
- result
+ return if self <= 0
+ (1..self).map { |e| 1 / e.to_r }.reduce(:+)
end
def digits
- abs.to_s.split('').map { |e| Integer(e) }
+ abs.to_s.chars.map { |e| e.to_i }
end
end
class Array
def average
- return nil if empty?
- result = 0.0
- each { |e| result = result + e }
-
- result / length
+ return if empty?
+ reduce(0.0, :+) / length
end
def drop_every(n)
result = []
- each_index do |index|
- result << self[index] if (index + 1) % n != 0
- end
+ each_index { |index| result << self[index] if (index + 1) % n != 0 }
result
end
def frequencies
- occurences = {}
- each do |number|
- if occurences.has_key?(number)
- occurences[number] = occurences[number] + 1
- else
- occurences[number] = 1
- end
- end
+ occurrences = Hash.new(0)
+ each { |number| occurrences[number] += 1 }
- occurences
+ occurrences
end
def combine_with(other_list)
smallest_length = other_list.length < length ? other_list.length : length
- result = []
+ combined_list = []
(0..smallest_length - 1).each do |number|
- result << self[number] << other_list[number]
+ combined_list << self[number] << other_list[number]
end
- adding_remaining_elements(smallest_length, other_list, result)
+ combined_list << other_list.drop(smallest_length) << drop(smallest_length)
- result
- end
-
- def adding_remaining_elements(smallest_length, other_list, result)
- if smallest_length == length
- other_list[smallest_length..other_list.length - 1].each{ |x| result << x }
- else
- self[smallest_length..length - 1].each{|x| result << x}
- end
+ combined_list.flatten
end
end