Теодор обнови решението на 21.10.2015 20:01 (преди над 9 години)
+def prime?(x)
+ return false if x <= 1
+ return true if x <= 3
+ return false if x % 2 == 0 or x % 3 == 0
+ i = 5
+ while i * i <= x
+ return false if x % i == 0
+ return false if x % (i + 2) == 0
+ i += 6
+ end
+ true
+end
+
+class RationalSequence
+ include Enumerable
+
+ def initialize(count)
+ @count = count
+ end
+
+ def each()
+ i, counter = 0, 0
+ while not end_reached?(counter)
+ rational, i = next_rational(i)
+ yield rational
+ counter += 1
+ end
+ end
+
+ private
+
+ def end_reached?(n)
+ @count != :infinite and n >= @count
+ end
+
+ def next_rational(i)
+ begin
+ point = [next_element(i, 0), next_element(i, 1)]
+ rational = Rational(point[0], point[1])
+ i += 1
+ end while point != [rational.numerator, rational.denominator]
+ [rational, i]
+ end
+
+ # Depending on the value of e, the function generetes
+ # the i-th member of one of the following sequences:
+ #
+ # e = 0 : 1 2 1|1 2 3 4 3 2 1|1 2 3 4 5 6 5 4 3 2 1|1 2 3 ...
+ # e = 1 : 1|1 2 3 2 1|1 2 3 4 5 4 3 2 1|1 2 3 4 5 6 7 6 5 ...
+ #
+ # The sequences are consisted of groups of type 1..2n-e..1
+ # where n is the index of the group.
+ def next_element(i, e)
+ group_index = calculate_group_index(i, e)
+ element_index = i - calculate_group_start(group_index, e)
+ get_group_member(group_index, element_index, e)
+ end
+
+ def calculate_group_index(i, e)
+ ((3 + 2 * e + Math.sqrt(8 * i + 1)) * 0.25).to_i
+ end
+
+ def calculate_group_start(n, e)
+ (2 * n - 1 - 2 * e) * (n - 1) - 1
+ end
+
+ def get_group_member(n, i, e)
+ 2 * n - e - (i - 2 * n + e).abs
+ end
+end
+
+class FibonacciSequence
+ include Enumerable
+
+ def initialize(count, first: 1, second: 1)
+ @count = count
+ @first = first
+ @second = second
+ end
+
+ def each()
+ a, b = @first, @second
+ (0 ... @count).each do
+ yield a
+ a, b = b, a + b
+ end
+ end
+end
+
+class PrimeSequence
+ include Enumerable
+
+ def initialize(count)
+ @count = count
+ end
+
+ def each()
+ p = 2
+ (0 ... @count).each do
+ yield p
+ while not prime? p += 1
+ end
+ end
+ end
+end
+
+module DrunkenMathematician
+ module_function
+
+ def answer
+ 42
+ end
+
+ def meaningless(n)
+ is_semi_prime = ->(x) { prime?(x.numerator) or prime?(x.denominator) }
+ RationalSequence.new(n).inject (1.to_r) do |result, x|
+ is_semi_prime[x] ? result * x : result / x
+ end
+ end
+
+ def aimless(n)
+ PrimeSequence.new(n).each_slice(2).inject 0.to_r do |result, (x, y)|
+ result + Rational(x, y || 1)
+ end
+ end
+
+ def worthless(n)
+ f = FibonacciSequence.new(n).max
+ RationalSequence.new(:infinite).take_while { |x| (f -= x) >= 0 }
+ end
+end