Живка обнови решението на 25.10.2015 21:38 (преди над 9 години)
+class RationalSequence
+ include Enumerable
+
+ def initialize(length_limit)
+ @length_limit = length_limit
+ @direction_key = :down
+ @length = 0
+ @data = []
+ end
+
+ def each
+ return @data unless @length_limit != 0
+ current = [1, 1]
+
+ while @length < @length_limit
+ rational_number = Rational(current[0], current[1])
+ @data << rational_number
+ yield rational_number
+ current = get_next_pair(current[0], current[1])
+ @length += 1
+ end
+ end
+
+ private
+
+ DIRECTIONS = {
+ down: [1, 0],
+ north_east: [-1, 1],
+ right: [0, 1],
+ south_west: [1, -1]
+ }
+
+ def update_direction_key()
+ case @direction_key
+ when :down
+ @direction_key = :north_east
+ when :north_east
+ @direction_key = :right
+ when :right
+ @direction_key = :south_west
+ else
+ @direction_key = :down
+ end
+ end
+
+ def get_next_pair(x, y)
+ direction = DIRECTIONS[@direction_key]
+ next_pair = [x, y].map.with_index { |item, index| item + direction[index] }
+
+ if next_pair.include? 1
+ update_direction_key()
+ end
+
+ if @data.include? Rational(next_pair[0], next_pair[1])
+ get_next_pair(next_pair[0], next_pair[1])
+ else
+ next_pair
+ end
+ end
+end
+
+class PrimeSequence
+ include Enumerable
+
+ def initialize(length_limit)
+ @length_limit = length_limit
+ end
+
+ def each
+ enum_for(:each_number).
+ lazy.
+ select { |x| DrunkenMathematician.prime?(x) }.first(@length_limit).each { |x| yield x }
+ end
+
+ private
+
+ def each_number
+ n = 1
+ loop do
+ n += 1
+ yield n
+ end
+ end
+end
+
+class FibonacciSequence
+ include Enumerable
+
+ def initialize(length_limit, first: 1, second: 1)
+ @length_limit = length_limit
+ @previous = second - first
+ @current = first
+ end
+
+ def each
+ return [] unless @length_limit != 0
+
+ length = 0
+ while length < @length_limit
+ yield @current
+ @current, @previous = @current + @previous, @current
+ length += 1
+ end
+ end
+end
+
+module DrunkenMathematician
+ module_function
+
+ def meaningless(n)
+ sequence = RationalSequence.new(n)
+ group_one = sequence.select { |x| prime?(x.numerator) or prime?(x.denominator) }
+ group_two = sequence.select { |x| !(prime?(x.numerator) or prime?(x.denominator)) }
+ group_one.reduce(1, :*)/group_two.reduce(1, :*)
+ end
+
+ def aimless(n)
+ prime_pairs = PrimeSequence.new(n).each_slice(2)
+ sequence = prime_pairs.map { |x| Rational(x[0], x[1]) }
+ sequence.reduce(0, :+)
+ end
+
+ def worthless(n)
+ fibonacci = FibonacciSequence.new(n).to_a.last
+ sum = 0
+ if !fibonacci or sum >= fibonacci
+ return []
+ end
+ max_length = 0
+ while sum <= fibonacci
+ max_length +=1
+ sum = RationalSequence.new(max_length).to_a.reduce(0, :+)
+ end
+ RationalSequence.new(max_length - 1).to_a
+ end
+
+ def prime?(number)
+ number == 1 or
+ number == 2 or
+ not (2..(number**0.5).floor).to_a.any? { |item| (number % item) == 0 }
+ end
+end