Решение на Трета задача от Александър Дражев

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

Към профила на Александър Дражев

Резултати

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

Код

class Integer < Numeric
def prime?
return false if self <= 1
2.upto(Math.sqrt(self).to_i) do |x|
return false if self % x == 0
end
true
end
end
class Sequence
include Enumerable
def initialize(count)
@count = count
end
end
class FibonacciSequence < Sequence
def initialize(count, first: 1, second: 1)
@count = count
@first = first
@second = second
end
def each
current, previous = @first, @second - @first
yielded_numbers = 0
while yielded_numbers < @count do
yield current
yielded_numbers += 1
current, previous = current + previous, current
end
end
end
class RationalSequence < Sequence
def each
numerator, denominator = 1, 1
yielded_numbers = 0
while yielded_numbers < @count do
if numerator.gcd(denominator) == 1
yield Rational(numerator, denominator)
yielded_numbers += 1
end
if numerator % 2 == denominator % 2
numerator += 1
denominator = [1, denominator - 1].max
else
numerator = [1, numerator - 1].max
denominator += 1
end
end
end
end
class PrimeSequence < Sequence
def each
current_prime = 2
yielded_numbers = 0
while yielded_numbers < @count do
if current_prime.prime?
yield current_prime
yielded_numbers += 1
end
current_prime += 1
end
end
end
module DrunkenMathematician
PHI = (1 + Math.sqrt(5)) / 2
module_function
def fibonacci(n)
((PHI**n - (-PHI)**(-n)) / Math.sqrt(5)).round
end
def aimless(n)
sum = 0
PrimeSequence.new(n).each_slice(2) { |s| sum += Rational(s[0], s[1] || 1) }
sum
end
def meaningless(n)
groups = RationalSequence.new(n).partition { |r| r.numerator.prime? or r.denominator.prime? }
groups[0].inject(1, :*) / groups[1].inject(1, :*)
end
def worthless(n)
sum = 0
limit = fibonacci(n)
RationalSequence.new(1.0/0).lazy.take_while { |r| (sum += r) <= limit }.to_a
end
end

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

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

Finished in 0.0124 seconds
20 examples, 0 failures

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

Александър обнови решението на 23.10.2015 07:06 (преди над 8 години)

+class Integer < Numeric
+ def prime?
+ return false if self <= 1
+ 2.upto(Math.sqrt(self).to_i) do |x|
+ return false if self%x == 0
+ end
+ true
+ end
+end
+
+class Sequence
+ include Enumerable
+
+ def initialize(count)
+ @count = count
+ end
+end
+
+class FibonacciSequence < Sequence
+ def initialize(count, first: 1, second: 1)
+ @count = count
+ @first = first
+ @second = second
+ end
+
+ def each
+ current, previous = @first, @second - @first
+ yielded_numbers = 0
+
+ while yielded_numbers < @count do
+ yield current
+ yielded_numbers += 1
+
+ current, previous = current + previous, current
+ end
+ end
+end
+
+class RationalSequence < Sequence
+ def each
+ numerator, denominator = 1, 1
+ yielded_numbers = 0
+
+ while yielded_numbers < @count do
+ if numerator.gcd(denominator) == 1
+ yield Rational(numerator, denominator)
+ yielded_numbers += 1
+ end
+
+ if numerator % 2 == denominator % 2
+ numerator += 1
+ denominator = [1, denominator - 1].max
+ else
+ numerator = [1, numerator - 1].max
+ denominator += 1
+ end
+ end
+ end
+end
+
+class PrimeSequence < Sequence
+ def each
+ current_prime = 2
+ yielded_numbers = 0
+
+ while yielded_numbers < @count do
+ if current_prime.prime?
+ yield current_prime
+ yielded_numbers += 1
+ end
+
+ current_prime += 1
+ end
+ end
+end
+
+module DrunkenMathematician
+ PHI = (1 + Math.sqrt(5)) / 2
+
+ module_function
+
+ def fibonacci(n)
+ ((PHI**n - (-PHI)**(-n)) / Math.sqrt(5)).round
+ end
+
+ def aimless(n)
+ sum = 0
+
+ PrimeSequence.new(n).each_slice(2) { |s| sum += Rational(s[0], s[1] || 1) }
+ sum
+ end
+
+ def meaningless(n)
+ groups = RationalSequence.new(n).partition { |r| r.numerator.prime? or r.denominator.prime? }
+ groups[0].inject(1, :*) / groups[1].inject(1, :*)
+ end
+
+ def worthless(n)
+ sum = 0
+
+ RationalSequence.new(1.0/0).lazy.take_while { |r| (sum += r) <= fibonacci(n) }.to_a
+ end
+end

Александър обнови решението на 23.10.2015 07:36 (преди над 8 години)

class Integer < Numeric
def prime?
return false if self <= 1
2.upto(Math.sqrt(self).to_i) do |x|
- return false if self%x == 0
+ return false if self % x == 0
end
true
end
end
class Sequence
include Enumerable
def initialize(count)
@count = count
end
end
class FibonacciSequence < Sequence
def initialize(count, first: 1, second: 1)
@count = count
@first = first
@second = second
end
def each
current, previous = @first, @second - @first
yielded_numbers = 0
while yielded_numbers < @count do
yield current
yielded_numbers += 1
current, previous = current + previous, current
end
end
end
class RationalSequence < Sequence
def each
numerator, denominator = 1, 1
yielded_numbers = 0
while yielded_numbers < @count do
if numerator.gcd(denominator) == 1
yield Rational(numerator, denominator)
yielded_numbers += 1
end
if numerator % 2 == denominator % 2
numerator += 1
denominator = [1, denominator - 1].max
else
numerator = [1, numerator - 1].max
denominator += 1
end
end
end
end
class PrimeSequence < Sequence
def each
current_prime = 2
yielded_numbers = 0
while yielded_numbers < @count do
if current_prime.prime?
yield current_prime
yielded_numbers += 1
end
current_prime += 1
end
end
end
module DrunkenMathematician
PHI = (1 + Math.sqrt(5)) / 2
module_function
def fibonacci(n)
((PHI**n - (-PHI)**(-n)) / Math.sqrt(5)).round
end
def aimless(n)
sum = 0
PrimeSequence.new(n).each_slice(2) { |s| sum += Rational(s[0], s[1] || 1) }
sum
end
def meaningless(n)
groups = RationalSequence.new(n).partition { |r| r.numerator.prime? or r.denominator.prime? }
groups[0].inject(1, :*) / groups[1].inject(1, :*)
end
def worthless(n)
sum = 0
RationalSequence.new(1.0/0).lazy.take_while { |r| (sum += r) <= fibonacci(n) }.to_a
end
end

Александър обнови решението на 23.10.2015 19:01 (преди над 8 години)

class Integer < Numeric
def prime?
return false if self <= 1
2.upto(Math.sqrt(self).to_i) do |x|
return false if self % x == 0
end
true
end
end
class Sequence
include Enumerable
def initialize(count)
@count = count
end
end
class FibonacciSequence < Sequence
def initialize(count, first: 1, second: 1)
@count = count
@first = first
@second = second
end
def each
current, previous = @first, @second - @first
yielded_numbers = 0
while yielded_numbers < @count do
yield current
yielded_numbers += 1
current, previous = current + previous, current
end
end
end
class RationalSequence < Sequence
def each
numerator, denominator = 1, 1
yielded_numbers = 0
while yielded_numbers < @count do
if numerator.gcd(denominator) == 1
yield Rational(numerator, denominator)
yielded_numbers += 1
end
if numerator % 2 == denominator % 2
numerator += 1
denominator = [1, denominator - 1].max
else
numerator = [1, numerator - 1].max
denominator += 1
end
end
end
end
class PrimeSequence < Sequence
def each
current_prime = 2
yielded_numbers = 0
while yielded_numbers < @count do
if current_prime.prime?
yield current_prime
yielded_numbers += 1
end
current_prime += 1
end
end
end
module DrunkenMathematician
PHI = (1 + Math.sqrt(5)) / 2
module_function
def fibonacci(n)
((PHI**n - (-PHI)**(-n)) / Math.sqrt(5)).round
end
def aimless(n)
sum = 0
PrimeSequence.new(n).each_slice(2) { |s| sum += Rational(s[0], s[1] || 1) }
sum
end
def meaningless(n)
groups = RationalSequence.new(n).partition { |r| r.numerator.prime? or r.denominator.prime? }
groups[0].inject(1, :*) / groups[1].inject(1, :*)
end
def worthless(n)
sum = 0
+ limit = fibonacci(n)
- RationalSequence.new(1.0/0).lazy.take_while { |r| (sum += r) <= fibonacci(n) }.to_a
+ RationalSequence.new(1.0/0).lazy.take_while { |r| (sum += r) <= limit }.to_a
end
end

На места имаш дребни стилови проблеми.

Като цяло, решението ти е една идея по-умно, отколкото може да бъде. За задачи с педагогическа цел е приемливо, но в реален, продукционен код, ако има по-семпло решение, удовлетворяващо функционалните и времеви изисквания, по-добре да се ползва то.

EDIT: Като цяло, решението е добро. Да не ме разбереш погрешно :)

Намирам за по-удачни за случая следните неща:

  • Integer#prime? от нашето примерно решение
  • Алтернативен FibonacciSequence#each (сходно и за другите):

      def each
        current, previous = @first, @second - @first
    
        @count.times do
          yield current
    
          current, previous = current + previous, current
        end
      end
    
  • по-добре да беше преизползвал FibonacciSequence в worthless

Идеята на задачите е по-скоро да се упражни този стил на писане, използващ много Enumerable и Enumerator и който е като цяло по-семпъл, включително използване на Array#first/last, вместо [0] или [1], избягване на неща като (sum += r) <= limit и т.н.

Ако ограниченията ти са дребни числа и рядко изпълнение на кода, какъв ще е смисълът от fibonacci, дефиниран по този начин в един реален проект (ако допуснем, че би имал случай да ти трябва fibonacci там)? Определено бих заложил на наивната имплементация там, защото ще е много по-лесно за поддръжка от колегите ми, включително и от бъдещото ми "аз".

За такива имплементации определено има място, дори в produciton код, просто в тези задачи целта е да покажем една друга гледна точка.

P.S. current_prime е всъщност current_number.