Решение на Първа задача от Антонио Николов

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

Към профила на Антонио Николов

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 12 успешни тест(а)
  • 2 неуспешни тест(а)

Код

class Integer
def prime?
return false if self < 1
(2..self / 2).all? { |i| self.remainder(i).nonzero? }
end
def prime_factors
count, primes, number = 2, [], self
until number.abs == 1
primes << count if number.remainder(count).zero?
number.remainder(count).zero? ? number /= count : count += 1
end
primes
end
def harmonic
return if self <= 0
Rational((1..self).inject { |sum, n| sum + Rational(1, n) })
end
def digits
number, digits = abs, []
until number == 0
digits << number.remainder(10)
number /= 10
end
digits.reverse
end
end
class Array
def frequencies
element_frequency = {}
each { |i| element_frequency[i] = count(i) if element_frequency[i] == nil }
element_frequency
end
def average
sum = 0.0
each { |i| sum += i }
sum / size
end
def drop_every(n)
remaining_elements = []
each_with_index do |item, i|
remaining_elements << item if (i + 1).remainder(n).nonzero?
end
remaining_elements
end
def combine_with(other)
short = if size <= other.size then size else other.size end
both = []
(0..short - 1).each { |i| both << self[i] & both << other[i] }
(short..other.size - 1).each { |i| both << other[i] } if short < other.size
(short..size - 1).each { |i| both << self[i] } if short < size
both
end
end

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

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

Failures:

  1) Integer#prime? checks if a number is prime
     Failure/Error: 1.prime?.should   eq false
       
       expected: false
            got: true
       
       (compared using ==)
     # /tmp/d20131023-4395-1k7uo6y/spec.rb:5: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)>'

  2) 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-1k7uo6y/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.01769 seconds
14 examples, 2 failures

Failed examples:

rspec /tmp/d20131023-4395-1k7uo6y/spec.rb:2 # Integer#prime? checks if a number is prime
rspec /tmp/d20131023-4395-1k7uo6y/spec.rb:43 # Integer#digits constructs an array containing the digits of a number

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

Антонио обнови решението на 13.10.2013 02:07 (преди около 11 години)

+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, например, които може да са ти полезни

Антонио обнови решението на 15.10.2013 00:29 (преди около 11 години)

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
+ return false if self < 1
+ (2..self / 2).all? { |i| self.remainder(i).nonzero? }
end
def prime_factors
- count, primes, number = 2, [], self
+ 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
+ primes << count if number.remainder(count).zero?
+ number.remainder(count).zero? ? number /= count : count += 1
end
- return p primes
+ 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
+ return if self <= 0
+ Rational((1..self).inject { |sum, n| sum + Rational(1, n) })
end
def digits
- number, arr_d = self.abs, []
+ number, digits = abs, []
until number == 0
- arr_d << number % 10
+ digits << number.remainder(10)
number /= 10
end
- return p arr_d.reverse
+ digits.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
+ element_frequency = {}
+ each { |i| element_frequency[i] = count(i) if element_frequency[i] == nil }
+ element_frequency
end
def average
- return p nil if self.empty?
sum = 0.0
- self.each { |x| sum += x }
- return p sum / self.size
+ each { |i| sum += i }
+ sum / 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
+ remaining_elements = []
+ each_with_index do |item, i|
+ remaining_elements << item if (i + 1).remainder(n).nonzero?
end
- return p no_n_elem
+ remaining_elements
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
+ short = if size <= other.size then size else other.size end
+ both = []
+ (0..short - 1).each { |i| both << self[i] & both << other[i] }
+ (short..other.size - 1).each { |i| both << other[i] } if short < other.size
+ (short..size - 1).each { |i| both << self[i] } if short < size
+ both
end
end