Бойко обнови решението на 22.10.2015 22:59 (преди над 9 години)
+class RationalSequence
+ include Enumerable
+
+ def initialize(limit, is_infinite = false)
+ @limit, @is_infinite = limit, is_infinite
+ end
+
+ def each
+ dividend = 1
+ divisor = 1
+ index = 1
+
+ loop do
+ yield Rational(dividend, divisor) if valid_quotient? dividend, divisor
+ break if index == @limit and not @is_infinite
+
+ dividend, divisor = next_dividend(dividend, divisor), next_divisor(dividend, divisor)
+ index += 1 if valid_quotient? dividend, divisor
+ end
+ end
+
+ private
+
+ def next_dividend(current_dividend, current_divisor)
+ if current_dividend % 2 == current_divisor % 2
+ current_dividend + 1
+ else
+ [current_dividend - 1, 1].max
+ end
+ end
+
+ def next_divisor(current_dividend, current_divisor)
+ if current_dividend % 2 == current_divisor % 2
+ [current_divisor - 1, 1].max
+ else
+ current_divisor + 1
+ end
+ end
+
+ def valid_quotient?(current_dividend, current_divisor)
+ current_dividend.gcd(current_divisor) == 1
+ end
+end
+
+class PrimeSequence
+ include Enumerable
+
+ def initialize(limit, limit_by_value = 0)
+ @limit, @limit_by_value = limit, limit_by_value
+ @known_primes = Array.new
+ end
+
+ def each
+ candidate = 2
+ while @known_primes.length < @limit or @limit_by_value > candidate
+ candidate += 1 while @known_primes.last == candidate or not has_divisors? candidate
+ @known_primes << candidate
+ yield @known_primes.last
+ end
+ end
+
+ private
+
+ def has_divisors?(number)
+ biggest_possible_divisor = Math.sqrt(number)
+ @known_primes.each do |known_prime|
+ break if known_prime > biggest_possible_divisor
+ return false if number % known_prime == 0
+ end
+
+ true
+ end
+end
+
+class FibonacciSequence
+ include Enumerable
+
+ def initialize(limit, first: 1, second: 1)
+ @limit, @first, @second = limit, first, second
+ end
+
+ def each
+ index = 0
+ while index < @limit
+ yield @first
+ @first, @second = @second, @first + @second
+ index += 1
+ end
+ end
+end
+
+module DrunkenMathematician
+ module_function
+
+ def answer
+ 42
+ end
+
+ def meaningless(n)
+ all_rationals = RationalSequence.new(n).to_a
+ prime_rationals, other_rationals = self.separate all_rationals
+
+ product(prime_rationals) / product(other_rationals)
+ end
+
+ def separate(all_rationals)
+ biggest_possible_number = all_rationals.last.denominator + all_rationals.last.numerator
+ primes = PrimeSequence.new(0, biggest_possible_number).to_a << 1
+ prime_rationals = all_rationals.select do |r|
+ primes.include?(r.denominator) and primes.include?(r.numerator)
+ end
+
+ other_rationals = all_rationals - prime_rationals
+
+ [prime_rationals, other_rationals]
+ end
+
+ def aimless(n)
+ rationals = PrimeSequence.new(n).each_slice(2).to_a.map do |couple|
+ Rational(couple[0], couple[1] || 1)
+ end
+
+ rationals.reduce(:+)
+ end
+
+ def worthless(n)
+ fibonacci = FibonacciSequence.new(n).to_a.last
+ rational_sequence = RationalSequence.new(0, true)
+
+ sum = 0
+ rational_sequence.take_while do |r|
+ sum += r
+ sum <= fibonacci
+ end
+ end
+
+ def product(rationals)
+ rationals.reduce(:*) || 1
+ end
+end