Решение на Първа задача от Калоян Калудов

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

Към профила на Калоян Калудов

Резултати

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

Код

class Integer
def prime?
return false if self < 2
2.upto(pred).all? { |number| remainder(number).nonzero? }
end
def primes_upto(number)
upto(number).select { |current_number| current_number.prime? }
end
def prime_divisors
2.primes_upto(self).select { |prime| remainder(prime).zero? }
end
def times_divided_by(number)
times_divided = 0
until remainder(number).nonzero?
number *= number
times_divided += 1
end
times_divided
end
def prime_factors
prime_divisors.map { |factor| [factor] * times_divided_by(factor) }.flatten
end
def harmonic
1.upto(self).reduce(Rational(0)) { |sum, i| sum + Rational(1, i) }
end
def digits
abs.to_s.chars.map { |character| character.to_i }
end
end
class Array
def frequencies
frequencies_hash = {}
each do |element|
frequencies_hash[element] = 0 unless frequencies_hash[element]
frequencies_hash[element] += 1
end
frequencies_hash
end
def average
reduce(0.0) { |sum, element| sum + element } / size
end
def drop_every(n)
new_array = []
each_slice(n) do |slice|
new_array += slice.size == n ? slice[0...-1] : slice
end
new_array
end
def combine_with(other)
larger_size = [size, other.size].max
(0..larger_size).map { |i| [self[i], other[i]] }.flatten.compact
end
end

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

.FF.........F.

Failures:

  1) Integer#prime_factors constructs an array containing the prime factors in ascending order
     Failure/Error: 360.prime_factors.should eq [2, 2, 2, 3, 3, 5]
       
       expected: [2, 2, 2, 3, 3, 5]
            got: [2, 2, 3, 3, 5]
       
       (compared using ==)
     # /tmp/d20131023-4395-1yq45tl/spec.rb:19: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#prime_factors works with negative numbers
     Failure/Error: (-4).prime_factors.should   eq [2, 2]
       
       expected: [2, 2]
            got: []
       
       (compared using ==)
     # /tmp/d20131023-4395-1yq45tl/spec.rb:27: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)>'

  3) Array#combine_with combines two arrays by alternatingly taking elements
     Failure/Error: [:a, :b, :c].combine_with([1, nil, 3]).should       eq [:a, 1, :b, nil, :c, 3]
       
       expected: [:a, 1, :b, nil, :c, 3]
            got: [:a, 1, :b, :c, 3]
       
       (compared using ==)
     # /tmp/d20131023-4395-1yq45tl/spec.rb:110: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.03268 seconds
14 examples, 3 failures

Failed examples:

rspec /tmp/d20131023-4395-1yq45tl/spec.rb:18 # Integer#prime_factors constructs an array containing the prime factors in ascending order
rspec /tmp/d20131023-4395-1yq45tl/spec.rb:26 # Integer#prime_factors works with negative numbers
rspec /tmp/d20131023-4395-1yq45tl/spec.rb:103 # Array#combine_with combines two arrays by alternatingly taking elements

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

Калоян обнови решението на 13.10.2013 21:07 (преди над 10 години)

+class Integer
+ def prime?
+ return false if self < 2
+ 2.upto(self-1).all? { |e| self.remainder(e).nonzero? }
+ end
+
+ def primes_upto n
+ self.upto(n).select { |e| e.prime? }
+ end
+
+ def prime_dividers
+ 2.primes_upto(self).select { |prime| self.remainder(prime).zero? }
+ end
+
+ def times_divided_by n
+ result = 0
+ until self.remainder(n).nonzero?
+ n *= n
+ result += 1
+ end
+ result
+ end
+
+ def prime_factors
+ self.prime_dividers.collect { |f| [f] * self.times_divided_by(f) }.flatten
+ end
+
+ def harmonic
+ 1.upto(self).inject(Rational(0)) { |sum,e| sum + Rational(1,e) }
+ end
+
+ def digits
+ self.abs.to_s.split("").collect { |c| c.to_i }
+ end
+end
+
+class Array
+ def frequencies
+ result = {}
+ self.each do |e|
+ result.store(e, 0) unless result.member? e
+ result[e] += 1
+ end
+ result
+ end
+
+ def average
+ self.inject(0.0, :+) / self.length
+ end
+
+ def drop_every n
+ result = []
+ self.each_slice(n) do |e|
+ result += if e.length == n then e[0...-1] else e end
+ end
+ result
+ end
+
+ def combine_with other
+ max = [self.length, other.length].max
+ (0..max).collect { |i| [self[i], other[i]] }.flatten.compact
+ end
+end

Малко бележки:

  • Идентацията на кода ти не е както трябва; консултирай се с ръководството по стил;
  • Конвенция - ред 4 - трябва да има интервали около -
  • Пак там, self - 1 е pred
  • Конвенция - ред 29 - трябва да има интервал след ,
  • Слагай скоби около дефиницията на методи, когато те имат аргументи (вж. секция Syntax в ръководството по стил)
  • Имена като result, e, c, f са лоши; съкращавайки няколко символа, не печелиш нищо, а губиш много; стреми се да спазваш clarity over brevity
  • Предпочитаме map пред collect и reduce пред inject
  • self. се "подразбира", когато предшества извикване на метод (ще го кажем по-натам) и е излишен; в почти всички такива случаи се пропуска (напр. ред 8, 12, 17, 25, 33, ...)
  • Ред 33, виж какво прави String#chars и опитай да измислиш по-добро име на c в този контекст
  • За да сложиш нещо в хеш, не ползваш store, a []=, т.е. hash[key] = value
  • Ред 41 - за да провериш дали вече няма число в хеша, може да ползваш и само ... unless result[e] (тук result и e са лоши имена); вместо result, спокойно може да ползваш frequencies, а e = element
  • Ред 54 - или ползвай тернарния оператор foo ? bar : baz, или, по-добре, нормален if/else; това не е много четимо
  • Ред 60, max е по-лошо име, от, larger_size, например
  • Предпочитаме size пред length

Калоян обнови решението на 15.10.2013 21:22 (преди над 10 години)

class Integer
def prime?
- return false if self < 2
- 2.upto(self-1).all? { |e| self.remainder(e).nonzero? }
+ return false if self < 2
+ 2.upto(pred).all? { |number| remainder(number).nonzero? }
end
- def primes_upto n
- self.upto(n).select { |e| e.prime? }
+ def primes_upto(number)
+ upto(number).select { |current_number| current_number.prime? }
end
- def prime_dividers
- 2.primes_upto(self).select { |prime| self.remainder(prime).zero? }
+ def prime_divisors
+ 2.primes_upto(self).select { |prime| remainder(prime).zero? }
end
- def times_divided_by n
- result = 0
- until self.remainder(n).nonzero?
- n *= n
- result += 1
- end
- result
+ def times_divided_by(number)
+ times_divided = 0
+ until remainder(number).nonzero?
+ number *= number
+ times_divided += 1
+ end
+ times_divided
end
def prime_factors
- self.prime_dividers.collect { |f| [f] * self.times_divided_by(f) }.flatten
+ prime_divisors.map { |factor| [factor] * times_divided_by(factor) }.flatten
end
def harmonic
- 1.upto(self).inject(Rational(0)) { |sum,e| sum + Rational(1,e) }
+ 1.upto(self).reduce(Rational(0)) { |sum, i| sum + Rational(1, i) }
end
def digits
- self.abs.to_s.split("").collect { |c| c.to_i }
+ abs.to_s.chars.map { |character| character.to_i }
end
end
class Array
def frequencies
- result = {}
- self.each do |e|
- result.store(e, 0) unless result.member? e
- result[e] += 1
+ frequencies_hash = {}
+ each do |element|
+ frequencies_hash[element] = 0 unless frequencies_hash[element]
+ frequencies_hash[element] += 1
end
- result
+ frequencies_hash
end
def average
- self.inject(0.0, :+) / self.length
+ reduce(0.0) { |sum, element| sum + element } / size
end
- def drop_every n
- result = []
- self.each_slice(n) do |e|
- result += if e.length == n then e[0...-1] else e end
+ def drop_every(n)
+ new_array = []
+ each_slice(n) do |slice|
+ new_array += slice.size == n ? slice[0...-1] : slice
end
- result
+ new_array
end
- def combine_with other
- max = [self.length, other.length].max
- (0..max).collect { |i| [self[i], other[i]] }.flatten.compact
+ def combine_with(other)
+ larger_size = [size, other.size].max
+ (0..larger_size).map { |i| [self[i], other[i]] }.flatten.compact
end
end