J'essaie d'implémenter la fonction suivante, mais elle continue de me donner l'erreur stack level too deep (SystemStackError)
.
Des idées sur le problème?
def fibonacci( n )
[ n ] if ( 0..1 ).include? n
( fibonacci( n - 1 ) + fibonacci( n - 2 ) ) if n > 1
end
puts fibonacci( 5 )
Essaye ça
def fibonacci( n )
return n if ( 0..1 ).include? n
( fibonacci( n - 1 ) + fibonacci( n - 2 ) )
end
puts fibonacci( 5 )
# => 5
consultez également cet article Fibonacci One-Liner
et plus .. https://web.archive.org/web/20120427224512/http://en.literateprograms.org/Fibonacci_numbers_ (Ruby)
Vous avez maintenant été bombardé de nombreuses solutions :)
concernant le problème dans votre solution
vous devez renvoyer n
si son 0
ou 1
et add
les deux derniers nombres ne sont pas le dernier et le suivant
Nouvelle version modifiée
def fibonacci( n )
return n if n <= 1
fibonacci( n - 1 ) + fibonacci( n - 2 )
end
puts fibonacci( 10 )
# => 55
Bon mot
def fibonacci(n)
n <= 1 ? n : fibonacci( n - 1 ) + fibonacci( n - 2 )
end
puts fibonacci( 10 )
# => 55
Voici quelque chose que j'ai trouvé, je trouve cela plus simple.
def fib(n)
n.times.each_with_object([0,1]) { |num, obj| obj << obj[-2] + obj[-1] }
end
fib(10)
Ce n'est pas ainsi que vous calculez fibonacci, vous créez un énorme arbre récursif qui échouera pour des n
s relativement petits. Je vous suggère de faire quelque chose comme ça:
def fib_r(a, b, n)
n == 0 ? a : fib_r(b, a + b, n - 1)
end
def fib(n)
fib_r(0, 1, n)
end
p (0..100).map{ |n| fib(n) }
linéaire
module Fib
def self.compute(index)
first, second = 0, 1
index.times do
first, second = second, first + second
end
first
end
end
récursif avec mise en cache
module Fib
@@mem = {}
def self.compute(index)
return index if index <= 1
@@mem[index] ||= compute(index-1) + compute(index-2)
end
end
Fermeture
module Fib
def self.compute(index)
f = fibonacci
index.times { f.call }
f.call
end
def self.fibonacci
first, second = 1, 0
Proc.new {
first, second = second, first + second
first
}
end
end
Aucune de ces solutions ne plantera votre système si vous appelez Fib.compute(256)
fib = Hash.new {|hash, key| hash[key] = key < 2 ? key : hash[key-1] + hash[key-2] }
fib[123] # => 22698374052006863956975682
Si vous vous demandez comment fonctionne cette initialisation de hachage, lisez ici:
PHI = 1.6180339887498959
TAU = 0.5004471413430931
def fibonacci(n)
(PHI**n + TAU).to_i
end
Vous n'avez pas besoin de récursivité.
La récursivité est très lente, voici un moyen plus rapide
a = []; a[0] = 1; a[1] = 1
i = 1
while i < 1000000
a[i+1] = (a[i] + a[i-1])%1000000007
i += 1
end
puts a[n]
C'est O (1), mais vous pouvez utiliser l'exponentiation matricielle, voici l'une des implémentations de la mienne, mais elle est en Java => http://Pastebin.com/DgbekCJM , mais les exp. matricielles O(8logn). Voici un algorithme beaucoup plus rapide, appelé doublage rapide. Voici une implémentation Java Java de doublage rapide).
class FD {
static int mod = 1000000007;
static long fastDoubling(int n) {
if(n <= 2) return 1;
int k = n/2;
long a = fastDoubling(k+1);
long b = fastDoubling(k);
if(n%2 == 1) return (a*a + b*b)%mod;
else return (b*(2*a - b))%mod;
}
Pourtant, en utilisant la multiplication karatsuba, les deux exp matrice. et le doublage rapide devient beaucoup plus rapide, mais le doublage rapide bat exp matrice. par un facteur constant, eh bien je ne voulais pas être très complet ici. Mais j'ai récemment fait beaucoup de recherches sur les nombres de fibonacci et je veux que mes recherches soient utiles à tous ceux qui veulent apprendre,;).
Cela peut vous aider.
def fib_upto(max)
i1, i2 = 1, 1
while i1 <= max
yield i1
i1, i2 = i2, i1+i2
end
end
fib_upto(5) {|f| print f, " "}
Essayez ce oneliner
def fib (n)
n == 0 || n == 1 ? n : fib(n-2) + fib(n-1)
end
print fib(16)
Sortie: 987
je pense que c'est assez facile:
def fibo(n) a=0 b=1 for i in 0..n c=a+b print "#{c} " a=b b=c end
end
Nous pouvons effectuer des séries de fibo de liste en utilisant l'algorithme ci-dessous
def fibo(n)
n <= 2 ? 1 : fibo(n-1) + fibo(n-2)
end
Nous pouvons générer des séries comme ci-dessous
p (1..10).map{|x| fibo(x)}
ci-dessous est la sortie de cette
=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
solution en ligne la plus rapide et la plus petite:
fiby = ->(n, prev, i, count, selfy) {
i < count ? (selfy.call n + prev, n, i + 1, count, selfy) : (puts n)
}
fiby.call 0, 1, 0, 1000, fiby
motif de selfie fonctionnel :)
a = [1, 1]
while(a.length < max) do a << a.last(2).inject(:+) end
Cela remplira a
avec la série. (Vous devrez considérer le cas lorsque max <2)
Si seul le nième élément est requis, vous pouvez utiliser Hash.new
fib = Hash.new {|hsh, i| hsh[i] = fib[i-2] + fib[i-1]}.update(0 => 0, 1 => 1)
fib[10]
# => 55
Voici une solution plus concise qui crée une table de recherche:
fibonacci = Hash.new do |hash, key|
if key <= 1
hash[key] = key
else
hash[key] = hash[key - 1] + hash[key - 2]
end
end
fibonacci[10]
# => 55
fibonacci
# => {1=>1, 0=>0, 2=>1, 3=>2, 4=>3, 5=>5, 6=>8, 7=>13, 8=>21, 9=>34, 10=>55}
Une autre approche du calcul des nombres de fibonacci en profitant de la mémorisation:
$FIB_ARRAY = [0,1]
def fib(n)
return n if $FIB_ARRAY.include? n
($FIB_ARRAY[n-1] ||= fib(n-1)) + ($FIB_ARRAY[n-2] ||= fib(n-2))
end
Cela garantit que chaque numéro de fibonacci n'est calculé qu'une seule fois, ce qui réduit considérablement le nombre d'appels à la méthode fib.
En voici un à Scala:
object Fib {
def fib(n: Int) {
var a = 1: Int
var b = 0: Int
var i = 0: Int
var f = 0: Int
while(i < n) {
println(s"f(${i+1}) -> $f")
f = a+b
a = b
b = f
i += 1
}
}
def main(args: Array[String]) {
fib(10)
}
}
Si vous voulez écrire l'algorithme fonctonal le plus rapide pour fib, il ne sera pas récursif. C'est l'une des rares fois où la manière fonctionnelle d'écrire une solution est plus lente. Parce que la pile se répète si vous utilisez quelque chose comme
fibonacci( n - 1 ) + fibonacci( n - 2 )
éventuellement n-1 et n-2 créeront le même nombre, donc des répétitions seront faites dans le calcul. Le moyen le plus rapide pour y parvenir est de manière itérative
def fib(num)
# first 5 in the sequence 0,1,1,2,3
fib1 = 1 #3
fib2 = 2 #4
i = 5 #start at 5 or 4 depending on wheather you want to include 0 as the first number
while i <= num
temp = fib2
fib2 = fib2 + fib1
fib1 = temp
i += 1
end
p fib2
end
fib(500)
C'est l'extrait que j'ai utilisé pour résoudre un défi de programmation chez URI Online Judge, j'espère que cela aide.
def fib(n)
if n == 1
puts 0
else
fib = [0,1]
(n-2).times do
fib << fib[-1] + fib[-2]
end
puts fib.join(' ')
end
end
fib(45)
Une sortie
# => 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733
Cela fait un moment, mais vous pouvez écrire une fonction d'une ligne assez élégante et simple:
def fib(n)
n > 1 ? fib(n-1) + fib(n-2) : n
end
Quelqu'un m'a demandé quelque chose de similaire aujourd'hui, mais il voulait obtenir un tableau avec une séquence de fibonacci pour un nombre donné. Par exemple,
fibo(5) => [0, 1, 1, 2, 3, 5]
fibo(8) => [0, 1, 1, 2, 3, 5, 8]
fibo(13) => [0, 1, 1, 2, 3, 5, 8, 13]
# And so on...
Voici ma solution. Il n'utilise pas la récursivité. Encore une solution si vous cherchez quelque chose de similaire: P
def fibo(n)
seed = [0, 1]
n.zero? ? [0] : seed.each{|i| i + seed[-1] > n ? seed : seed.Push(i + seed[-1])}
end
encore un autre ;)
def fib(n)
f = Math.sqrt(5)
((((1+f)/2)**n - ((1-f)/2)**n)/f).to_i
end
sera également utile d'ajouter un peu de cache
def fibonacci
@fibonacci ||= Hash.new {|h,k| h[k] = fib k }
end
nous serons donc en mesure de l'obtenir comme
fibonacci[3] #=> 2
fibonacci[10] #=> 55
fibonacci[40] #=> 102334155
fibonacci #=> {3=>2, 10=>55, 40=>102334155}
1) Exemple, où l'élément max <100
def fibonachi_to(max_value)
fib = [0, 1]
loop do
value = fib[-1] + fib[-2]
break if value >= max_value
fib << value
end
fib
end
puts fibonachi_to(100)
Production:
0
1
1
2
3
5
8
13
21
34
55
89
2) Exemple, où 10 éléments
def fibonachi_of(numbers)
fib = [0, 1]
(2..numbers-1).each { fib << fib[-1] + fib[-2] }
fib
end
puts fibonachi_of(10)
Production:
0
1
1
2
3
5
8
13
21
34
Je pense c'est la meilleure réponse , qui était une réponse d'un autre SO message posant une question similaire.
La réponse acceptée de PriteshJ
ici utilise la récursion naïve de fibonacci, ce qui est bien, mais devient extrêmement lent une fois que vous avez dépassé le 40ème élément. C'est beaucoup plus rapide si vous mettez en cache/mémorisez les valeurs précédentes et les transmettez pendant que vous itérez récursivement.
Rejoindre le train Fibonacci:
Régulier:
def fib(num)
return num if (num < 2) else fib(num-1) + fib(num-2)
end
Avec mise en cache:
module Fib
@fibs = [0,1]
def self.calc(num)
return num if (num < 2) else @fibs[num] ||= self.calc(num-1) + self.calc(num-2)
end
end