Добромир обнови решението на 22.10.2015 19:14 (преди над 9 години)
+class RationalSequence
+ include Enumerable
+
+ def initialize(limit = 0)
+ @limit = limit
+ end
+
+ def each
+ (1..Float::INFINITY).each do |n|
+ rationals_slice(n) do |rational|
+ yield rational
+ end
+ end
+ end
+
+ def to_a
+ collection = []
+ return collection if @limit <= 0
+
+ each do |rational|
+ collection.push rational
+ return collection if collection.size == @limit
+ end
+ end
+
+ private
+
+ def rationals_slice(slice)
+ slice.downto(1) do |n|
+ numerator, denominator = slice - (n - 1), n
+
+ if numerator.gcd(denominator) == 1 and slice.odd?
+ yield Rational(numerator, denominator)
+ elsif numerator.gcd(denominator) == 1
+ yield Rational(denominator, numerator)
+ end
+ end
+ end
+end
+
+class PrimeSequence
+ include Enumerable
+
+ def initialize(limit)
+ @limit = limit
+ end
+
+ def each
+ (1..Float::INFINITY).each {|n| yield n if is_prime? n}
+ end
+
+ def to_a
+ collection = []
+ return collection if @limit <= 0
+
+ each do |rational|
+ collection.push rational
+ return collection if collection.size == @limit
+ end
+ end
+
+ private
+
+ def is_prime? number
+ return false if number <= 1
+ Math.sqrt(number).to_i.downto(2).each {|i| return false if number % i == 0}
+ true
+ end
+end
+
+class FibonacciSequence
+ include Enumerable
+
+ def initialize(limit, first: 1, second: 1)
+ @limit, @first, @second = limit, first, second
+ end
+
+ def each
+ (1..Float::INFINITY).each {|n| yield fibonacci(n)}
+ end
+
+ def to_a
+ collection = []
+ return collection if @limit <= 0
+
+ each do |rational|
+ collection.push rational
+ return collection if collection.size == @limit
+ end
+ end
+
+ private
+ def fibonacci(n)
+ return @first if n == 1
+ return @second if n == 2
+
+ fibonacci(n - 1) + fibonacci(n - 2)
+ end
+end
+
+module DrunkenMathematician
+ module_function
+
+ def meaningless(n)
+ rationals = RationalSequence.new(n).to_a
+
+ group_one = rationals.select do |rational|
+ is_prime? rational.numerator or is_prime? rational.denominator
+ end
+ group_two = rationals.select do |rational|
+ not is_prime? rational.numerator and not is_prime? rational.denominator
+ end
+
+ group_one.reduce(1, :*) / group_two.reduce(1, :*)
+ end
+
+ def aimless(n)
+ primes = PrimeSequence.new(n).to_a
+ primes.each_slice(2).to_a.map {|slice| Rational(*slice)}.reduce(:+)
+ end
+
+ def worthless(n)
+ fibonacci_number = FibonacciSequence.new(n).to_a.last
+ rationals_slice = []
+
+ RationalSequence.new.each do |rational|
+ rationals_slice.push rational
+ if rationals_slice.reduce(:+) > fibonacci_number
+ return rationals_slice.slice(0...rationals_slice.size - 1)
+ end
+ end
+ end
+
+ def is_prime? number
+ return false if number <= 1
+ Math.sqrt(number).to_i.downto(2).each {|i| return false if number % i == 0}
+ true
+ end
+end
Това с default-ната стойност на @limit
не е супер трагично, но не е и напълно ok. Променяш публичния интерфейс на задачата.
Относно each
и to_a
- това вече не е ok. По принцип когато видиш някакъв обект, който отговаря и на двата метода, очакването е x.each &some_block
и x.to_a.each &some_block
yield-ват еднакво, с точност до laziness. Също няма да ти работят останалите методи от Enumerable
по начина, по който би се очаквало.