Решение на Първа задача от Кристиан Ташков

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

Към профила на Кристиан Ташков

Резултати

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

Код

class Integer
def prime?
return false if self < 2
upper_limit = (self / 2).ceil
(2..upper_limit).map { |number| remainder(number).zero? }.none?
end
def times_divisible_by(number, current = self)
if current % number == 0
1 + times_divisible_by(number , current / number)
else
0
end
end
def prime_factors
primes = (2..self.abs).select(&:prime?)
primes.flat_map { |prime| Array.new(times_divisible_by(prime), prime) }
end
def harmonic
(1..self).map { |number| 1r / number }.reduce(:+)
end
def digits
abs.to_s.chars.map(&:to_i)
end
end
class Array
def frequencies
reduce(Hash.new(0)) do |frequencies, element|
frequencies[element] += 1
frequencies
end
end
def average
reduce(0.0, :+) / size
end
def drop_every(n)
each_with_index.reject { |_ , i| (1 + i).remainder(n).zero? }.map(&:first)
end
def combine_with(other)
if length < other.length
same_length_part = self
leftover_part = other.drop(length)
else
same_length_part = take(other.length)
leftover_part = drop(other.length)
end
(same_length_part.zip(other) << leftover_part).flatten
end
end

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

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

Finished in 0.34789 seconds
14 examples, 0 failures

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

Кристиан обнови решението на 13.10.2013 00:10 (преди над 10 години)

+class Integer
+ def prime?
+ return false if self < 2
+ not (2..(self / 2).ceil).map { |x| self % x == 0 }.any?
+ end
+
+ def times_divisible_by(x, current = self)
+ if current % x == 0
+ 1 + times_divisible_by(x , current / x)
+ else
+ 0
+ end
+ end
+
+ def prime_factors
+ primes = (2..self.abs).select(&:prime?)
+ primes.map { |x| Array.new(self.times_divisible_by(x), x) }.flatten
+ end
+
+ def harmonic
+ (1..self).map { |x| 1r/ x }.reduce(:+)
+ end
+
+ def digits
+ self.abs.to_s.chars.map { |x| Integer(x) }
+ end
+end
+
+class Array
+ def frequencies
+ self.reduce(Hash.new(0)) do |map, x|
+ map[x] += 1
+ map
+ end
+ end
+
+ def average
+ self.reduce(0.0, :+) / self.length
+ end
+
+ def drop_every(n)
+ self.each_with_index.select { |_ , i| (1 + i) % n != 0 }.map(&:first)
+ end
+
+ def combine_with(other)
+ if self.length < other.length
+ first = self
+ left_over = other.drop(first.length)
+ else
+ first = self.take(other.length)
+ left_over = self.drop(first.length)
+ end
+
+ (first.zip(other) << left_over).flatten
+ end
+end

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

  • На ред 4, any? може да се извиква и с блок; виж дали има как да го ползваш; освен това, вместо not ...any?, може да ползваш none?
  • Недостатъчно добре четим е този израз в range-а на ред 4; изведи горната граница в променлива
  • Допълнително, предпочитаме вариантите с думи на проверката за делимост, т.е. remainder(number) и методите zero? и nonzero?
  • x не е добро име; number е по-добро
  • Доста извратен начин си намерил да напишеш prime_factors - трудно се разбира :) Между другото, може да ползваш flat_map там, вместо map { ... }.flatten
  • self. се "подразбира", когато предшества извикване на метод (ще го кажем по-натам) и е излишен; в почти всички такива случаи се пропуска (напр. ред 16, 17, 25, 31, 38...)
  • Ред 21, трябва интервал преди /
  • Ред 25, методът, който търсиш, е String#to_i
  • Ред 31, map е лошо име; frequencies е по-добро; предпочитам и x да е кръстено element
  • Ред 42, reject е по-близо до идеята на drop_every, отколкото select, според мен; дургото е интересно решение
  • "leftover" е една дума :) и някак си не ми се връзва с "first"; пробвай да намериш друга комбинация от думи; може би "head" + "tail" ми звучи по-добре, дори, отколкото тези двете

Иначе, решението ти е прилично, поздравления!

Кристиан обнови решението на 15.10.2013 16:03 (преди над 10 години)

class Integer
def prime?
return false if self < 2
- not (2..(self / 2).ceil).map { |x| self % x == 0 }.any?
+ upper_limit = (self / 2).ceil
+ (2..upper_limit).map { |number| remainder(number).zero? }.none?
end
- def times_divisible_by(x, current = self)
- if current % x == 0
- 1 + times_divisible_by(x , current / x)
+ def times_divisible_by(number, current = self)
+ if current % number == 0
+ 1 + times_divisible_by(number , current / number)
else
0
end
end
def prime_factors
primes = (2..self.abs).select(&:prime?)
- primes.map { |x| Array.new(self.times_divisible_by(x), x) }.flatten
+ primes.flat_map { |prime| Array.new(times_divisible_by(prime), prime) }
end
def harmonic
- (1..self).map { |x| 1r/ x }.reduce(:+)
+ (1..self).map { |number| 1r / number }.reduce(:+)
end
def digits
- self.abs.to_s.chars.map { |x| Integer(x) }
+ abs.to_s.chars.map(&:to_i)
end
end
class Array
def frequencies
- self.reduce(Hash.new(0)) do |map, x|
- map[x] += 1
- map
+ reduce(Hash.new(0)) do |frequencies, element|
+ frequencies[element] += 1
+ frequencies
end
end
def average
- self.reduce(0.0, :+) / self.length
+ reduce(0.0, :+) / size
end
def drop_every(n)
- self.each_with_index.select { |_ , i| (1 + i) % n != 0 }.map(&:first)
+ each_with_index.reject { |_ , i| (1 + i).remainder(n).zero? }.map(&:first)
end
def combine_with(other)
- if self.length < other.length
- first = self
- left_over = other.drop(first.length)
+ if length < other.length
+ same_length_part = self
+ leftover_part = other.drop(length)
else
- first = self.take(other.length)
- left_over = self.drop(first.length)
+ same_length_part = take(other.length)
+ leftover_part = drop(other.length)
end
- (first.zip(other) << left_over).flatten
+ (same_length_part.zip(other) << leftover_part).flatten
end
end