Skip to content

Instantly share code, notes, and snippets.

@cbaykam
Last active May 22, 2018 10:25
Show Gist options
  • Save cbaykam/55b15ce6053a2af081b0973fed790bb3 to your computer and use it in GitHub Desktop.
Save cbaykam/55b15ce6053a2af081b0973fed790bb3 to your computer and use it in GitHub Desktop.
Even Fibonacci Numbers
# Uses matrix exponantion algorithm to solve fibonacci sequences
# Complexity O(log n)
# Usage :
# f = FibonacciSolver.new
# f.sum_even(max_value)
# Example: below class declaration, Uncomment to test.
class FibonacciSolver
# calculates the fibonacci sequence's (n)th element
def fib(n)
# Because the first element is 1 we get the n+1 in the matrix multiplication
calculate_fib(n)[1]
end
# Sums the even values until it reaches the maxiumu value
def sum_even(max)
validate!(max)
res = 0
collection = create_collection(max)
collection.each do |val|
res += val if val.even?
end
res
end
# creates an array of fibonacci sequence until the max value is reached
def create_collection(max)
res = []
val = 0
i = 0
while val < max do
val = fib(i)
res << val
i = i.next
end
res
end
private
# Recursive method to calculate matrix multiplication formula
# Fib(2n) = Fib(n) * [2 * Fib(n+1) - Fib(n)]
# Fib(2n + 1) = Fib(n + 1) ^ 2 + Fib(n) ^ 2
def calculate_fib(n)
if n == 0
[0, 1]
else
elements = calculate_fib(n / 2)
a = elements[0]
b = elements[1]
c = a * ( b * 2 - a )
d = (a ** 2) + (b ** 2)
if n.even?
[c, d]
else
[d, (d + c)]
end
end
end
def validate!(val)
raise ArgumentError, 'Invalid integer' unless val.is_a? Integer
end
end
# f = FibonacciSolver.new
# f.sum_even(4000000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment