Najpierw potrzebujemy szybkiej funkcji do wyliczenia sekwencji fib (wersja rekurencyjna w Ruby 1.8.6) jest za wolna dla n > 30 :
def fib(n)
a,b = 0,1
n.times { a+=b; a,b=b,a}
a
end
Teraz budujemy tablicę wartości z sekwencji które spełniają podane warunki:
code=ruby.map {|x| fib(x)}.select {|x| x % 2 == 0 && x < 4000000}.inject {|sum,n| sum+n}
=> 4613732[/code]
Rozwiązanie wg. mnie jest OK ale nie podoba mi się założenie z góry (1…100) na początku (zakładam że wiem że fib(100) jest o wiele większe niż 4 miliony)
fi = (1 + Math.sqrt(5)) / 2[/code]
Cały kod poniżej:
[code=Ruby]found = false
n = sum = 0
fn_max = 4000000
fi = (1 + Math.sqrt(5)) / 2
while !found
n += 1
fn = ((fi ** n - (1 - fi) ** n) / Math.sqrt(5)).to_i
sum += fn if (fn % 2 == 0) && (fn < fn_max)
found = true if fn > fn_max
end
p sum
def fibonacci(max)
l1, l2 = 1, 2
n = []
while l1 <= max
n.push(l1)
l1, l2 = l2, l1 + l2
end
result = n
end
puts fibonacci(4000000)
wynik = fibonacci(4000000).inject {|suma, element| suma+element}
puts wynik # 9227463
Co może być przyczyną złego wyniku?
[quote=Shot]IMHO najładniejsza kombinacja powyższych to:
fib = [1,2]
fib << fib[-1] + fib[-2] while fib.last < 4_000_000
fib.select(&:even?).inject(:+) # => 4613732
[/quote]
Tak właśnie się zorientowałem, że powinno być:
fib = [1,2]
fib << fib[-1] + fib[-2] while fib[-1] + fib[-2] < 4_000_000
fib.select(&:even?).inject(:+) # => 4613732
I tylko dlatego, że pierwszy element tablicy przekraczający 4M jest nieparzysty (5_702_887) program daje poprawny wynik…