Newbie here! Trying to implement a program to print the first 20 Fibonacci numbers in Ruby. I've managed to create a program which generates the nth number, but I want to produce all from 0 through to 20.
Is there a simple way to do this or do I need to rewrite the whole program?
CURRENT CODE
def fib(n)
if n < 1
return 0
elsif n == 1
return 1
else fib(n-2) fib(n-1)
end
end
puts fib(20)
CURRENT OUTPUT EXAMPLE
6765
DESIRED OUTCOME
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
CodePudding user response:
At the moment you only print the last value returned by your method (fib(20)
) but not the result of all intermediate steps.
An easy way would be to cache all intermediate results in a hash data structure. This would also improve performance for big n
because you do not need to recalculate many values over and over again.
Then you can just print out all results from 0
to n
:
def cached_fib(n)
@cache ||= Hash.new do |cache, n|
@cache[n] = n < 2 ? n : cache[n-1] cache[n-2]
end
@cache[n]
end
def fib(n)
0.upto(n) { |i| puts cached_fib(i) }
end
fib(20)
#=> 0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
CodePudding user response:
Printing each value is easier with a button-up approach where you start at 0
and 1
and calculate each following value based on its predecessors, e.g.:
i, j = 0, 1
puts i
puts j
21.times do
k = i j
puts k
i, j = j, k
end
You could turn the above into an Enumerator
:
fib = Enumerator.new do |y|
i, j = 0, 1
y << i
y << j
loop do
k = i j
y << k
i, j = j, k
end
end
Which will generate the sequence:
fib.take(21)
#=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,
# 233, 377, 610, 987, 1597, 2584, 4181, 6765]