Recursive fibonacci ruby
Author: c | 2025-04-25
Fibonacci sequence in Ruby (recursion) 0. Explanation of Recursion with Fibonacci Numbers. 5. Ruby Fibonacci algorithm. 1. Ruby Sum of Integers for Fibonacci Sequence. 2. Fibonacci sequence in Ruby (recursion) 0. Explanation of Recursion with Fibonacci Numbers. 5. Ruby Fibonacci algorithm. 1. Optimizing a recurisive fibonacci method. 1. Recursive solution
Recursion, Fibonacci, and Speed with Ruby
!macOS-11.1!ruby-2.7.2p137Preface (Introduction)Output the Fibonacci sequence using a recursive function.FibonacciThe fib function, which returns the Fibonacci number, has the following relationship.fib(n) = fib(n-1)+fib(n-2)0 1 1 2 3 5 8 13 21 ...fib(0) = 0Since the first term fib (0) of the Fibonacci sequence is defined as 0fibonacci.rbdef fib(n) if n==0 return 0 endendwill do.Use the previously created assert \ _equal for this test.fibonacci.rbrequire './assert_equal'puts assert_equal(0, fib(0))The output is> ruby fibonacci.rbexpected :: 0result :: 0succeeded in assert_equal.It worked as expected.fib(1) = 1The second term fib (1) of the Fibonacci sequence is defined as 1, so add to the above code.fibonacci.rbrequire './assert_equal'def fib(n) if n==0 return 0 elsif n==1 return 1 endendputs assert_equal(0, fib(0))puts assert_equal(1, fib(1))The output isexpected :: 0result :: 0succeeded in assert_equal.expected :: 1result :: 1succeeded in assert_equal.This is also as expected.fib(n) = fib(n-1) + fib(n-2)Even if n becomes larger from here, I will return the Fibonacci number properly. Before that, it was messed up so I will refresh it once.fibonacci.rbdef fib(n) return 0 if n==0 return 1 if n==2endFurthermore, the processing of fib (n) = fib (n-1) + fib (n-2) is added.fibonacci.rbdef fib(n) return 0 if n==0 return 1 if n==1 return fib(n-1) + fib(n-2)endUse Array.each to clean the test for confirmation.fibonacci.rb[[0,0], [1,1],[2,1],[3,2],[4,3],[5,5],[6,8],[7,13],[8,21],[9,34]].each do |index, expected| puts assert_equal(expected, fib(index))endThe output isexpected :: 0result :: 0succeeded in assert_equal.expected :: 1result :: 1succeeded in assert_equal.expected :: 1result :: 1succeeded in assert_equal.expected :: 2result :: 2succeeded in assert_equal.expected :: 3result :: 3succeeded in assert_equal.expected :: 5result :: 5succeeded in assert_equal.expected :: 8result :: 8succeeded in assert_equal.expected :: 13result :: 13succeeded in assert_equal.expected :: 21result :: 21succeeded in assert_equal.expected :: 34result :: 34succeeded in assert_equal.This also worked fine.bonusAt this rate, as n increases, the processing becomes exponentially heavy. The reason is that fib (n-1) and fib (n-2) are calculated separately to obtain fib (n).Therefore, let's lighten the process by using a technique called memoization recursion.fibonacci_opt.rb@memo = {}def fib(n) return @memo[n] if @memo.has_key?(n) return 0 if n == 0 return 1 if n == 1 return @memo[n] = fib(n-1) + fib(n-2)endputs fib(100)The output is> ruby fibonacci_opt.rb-> 354224848179261915075This result was correct.Reference material-Chart type ruby-V (Recursive Fibonacci)-Story of speed improvement by memoization-Fibonacci sequence up to 100th Fibonacci sequence in Ruby (recursion) 0. Explanation of Recursion with Fibonacci Numbers. 5. Ruby Fibonacci algorithm. 1. Ruby Sum of Integers for Fibonacci Sequence. 2. Definition with the help of an example. int fun(int z){ printf(“%d”,z); fun(z-1); //Recursive call is last executed statement}If you observe this program, you can see that the last line ADI will execute for method fun is a recursive call. And because of that, there is no need to remember any previous state of the program.Non-Tailed RecursionA recursive function is said to be non-tail recursive if the recursion call is not the last thing done by the function. After returning back, there is something left to evaluate. Now, consider this example.int fun(int z){ fun(z-1); printf(“%d”,z); //Recursive call is not the last executed statement}In this function, you can observe that there is another operation after the recursive call. Hence the ADI will have to memorize the previous state inside this method block. That is why this program can be considered non-tail recursive. Moving forward, you will implement a C program that exhibits recursive algorithmic nature.[Related reading: How to Learn Programming?]Program to Demonstrate RecursionYou will look at a C program to understand recursion in the case of the sum of n natural numbers problem.#includeint Sum(int n){ if(n==0){ return 0; } int temp = Sum(n-1); return n + temp;}int main(){ int n; printf("Enter the natural number n to calculate the sum of n numbers: "); scanf("%d",&n); printf("%d",Sum(n));}Output:The output for the sum of n natural numbers program is represented in the image below.Memory Allocation of Recursive MethodEach recursive call generates a new copy of the function on stack memory. Once the procedure returns some data, the copy is deleted from storage. Each recursive call maintains a separate stack because all parameters and other variables defined inside functions are kept on the stack. The stack is deleted after the value from the relevant function is returned. Recursion is quite complicated in terms of resolving and monitoring the values at each recursive call. As a result, you have to maintain the stack and track the values of the variables specified in it. To better understand the memory allocation of recursive functions, examine the following example.//Fibonacci program recursive Functionint Fib(int num){ if ( num == 0 ) return 0; else if ( num == 1 ) return 1; else return ( Fib(num-1) + Fib(num - 2) );} //Let’s say we want to calculate Fibonacci number for n=5Fib(5)Now, have a look at this recursive Fibonacci code for n = 5. First, all stacks are preserved, each of which prints the matching value of n until n becomes zero. When the termination condition is achieved, the stacks are destroyed one at a time by returning 0 to their calling stack. To understand the call stack hierarchy, look at the figure below.ConclusionIn this recursive algorithm tutorial, you learned what a recursiveComments
!macOS-11.1!ruby-2.7.2p137Preface (Introduction)Output the Fibonacci sequence using a recursive function.FibonacciThe fib function, which returns the Fibonacci number, has the following relationship.fib(n) = fib(n-1)+fib(n-2)0 1 1 2 3 5 8 13 21 ...fib(0) = 0Since the first term fib (0) of the Fibonacci sequence is defined as 0fibonacci.rbdef fib(n) if n==0 return 0 endendwill do.Use the previously created assert \ _equal for this test.fibonacci.rbrequire './assert_equal'puts assert_equal(0, fib(0))The output is> ruby fibonacci.rbexpected :: 0result :: 0succeeded in assert_equal.It worked as expected.fib(1) = 1The second term fib (1) of the Fibonacci sequence is defined as 1, so add to the above code.fibonacci.rbrequire './assert_equal'def fib(n) if n==0 return 0 elsif n==1 return 1 endendputs assert_equal(0, fib(0))puts assert_equal(1, fib(1))The output isexpected :: 0result :: 0succeeded in assert_equal.expected :: 1result :: 1succeeded in assert_equal.This is also as expected.fib(n) = fib(n-1) + fib(n-2)Even if n becomes larger from here, I will return the Fibonacci number properly. Before that, it was messed up so I will refresh it once.fibonacci.rbdef fib(n) return 0 if n==0 return 1 if n==2endFurthermore, the processing of fib (n) = fib (n-1) + fib (n-2) is added.fibonacci.rbdef fib(n) return 0 if n==0 return 1 if n==1 return fib(n-1) + fib(n-2)endUse Array.each to clean the test for confirmation.fibonacci.rb[[0,0], [1,1],[2,1],[3,2],[4,3],[5,5],[6,8],[7,13],[8,21],[9,34]].each do |index, expected| puts assert_equal(expected, fib(index))endThe output isexpected :: 0result :: 0succeeded in assert_equal.expected :: 1result :: 1succeeded in assert_equal.expected :: 1result :: 1succeeded in assert_equal.expected :: 2result :: 2succeeded in assert_equal.expected :: 3result :: 3succeeded in assert_equal.expected :: 5result :: 5succeeded in assert_equal.expected :: 8result :: 8succeeded in assert_equal.expected :: 13result :: 13succeeded in assert_equal.expected :: 21result :: 21succeeded in assert_equal.expected :: 34result :: 34succeeded in assert_equal.This also worked fine.bonusAt this rate, as n increases, the processing becomes exponentially heavy. The reason is that fib (n-1) and fib (n-2) are calculated separately to obtain fib (n).Therefore, let's lighten the process by using a technique called memoization recursion.fibonacci_opt.rb@memo = {}def fib(n) return @memo[n] if @memo.has_key?(n) return 0 if n == 0 return 1 if n == 1 return @memo[n] = fib(n-1) + fib(n-2)endputs fib(100)The output is> ruby fibonacci_opt.rb-> 354224848179261915075This result was correct.Reference material-Chart type ruby-V (Recursive Fibonacci)-Story of speed improvement by memoization-Fibonacci sequence up to 100th
2025-04-21Definition with the help of an example. int fun(int z){ printf(“%d”,z); fun(z-1); //Recursive call is last executed statement}If you observe this program, you can see that the last line ADI will execute for method fun is a recursive call. And because of that, there is no need to remember any previous state of the program.Non-Tailed RecursionA recursive function is said to be non-tail recursive if the recursion call is not the last thing done by the function. After returning back, there is something left to evaluate. Now, consider this example.int fun(int z){ fun(z-1); printf(“%d”,z); //Recursive call is not the last executed statement}In this function, you can observe that there is another operation after the recursive call. Hence the ADI will have to memorize the previous state inside this method block. That is why this program can be considered non-tail recursive. Moving forward, you will implement a C program that exhibits recursive algorithmic nature.[Related reading: How to Learn Programming?]Program to Demonstrate RecursionYou will look at a C program to understand recursion in the case of the sum of n natural numbers problem.#includeint Sum(int n){ if(n==0){ return 0; } int temp = Sum(n-1); return n + temp;}int main(){ int n; printf("Enter the natural number n to calculate the sum of n numbers: "); scanf("%d",&n); printf("%d",Sum(n));}Output:The output for the sum of n natural numbers program is represented in the image below.Memory Allocation of Recursive MethodEach recursive call generates a new copy of the function on stack memory. Once the procedure returns some data, the copy is deleted from storage. Each recursive call maintains a separate stack because all parameters and other variables defined inside functions are kept on the stack. The stack is deleted after the value from the relevant function is returned. Recursion is quite complicated in terms of resolving and monitoring the values at each recursive call. As a result, you have to maintain the stack and track the values of the variables specified in it. To better understand the memory allocation of recursive functions, examine the following example.//Fibonacci program recursive Functionint Fib(int num){ if ( num == 0 ) return 0; else if ( num == 1 ) return 1; else return ( Fib(num-1) + Fib(num - 2) );} //Let’s say we want to calculate Fibonacci number for n=5Fib(5)Now, have a look at this recursive Fibonacci code for n = 5. First, all stacks are preserved, each of which prints the matching value of n until n becomes zero. When the termination condition is achieved, the stacks are destroyed one at a time by returning 0 to their calling stack. To understand the call stack hierarchy, look at the figure below.ConclusionIn this recursive algorithm tutorial, you learned what a recursive
2025-04-16Had continued to play around + systematically tried different relaxations. But I didn't, so I didn't. Only nasty to find diameter of general graphs, right? If you know you have a tree, just root it at a random vertex and recursively compute `max(largest diameter of children, sum of the two biggest heights of children)` What bothers me a bit, is that in example where we trying to find Levenstein distance between two string are we 100% sure that calculated distance from end of string to the start will result in the same value as when we calculate distance from start to end? That's a very good question.I think the simplest approach to prove it would be to show that both computations yield the global minimum. Since there is only one global minimum, then they must be equal. Reminds me of how the mathematician behind DP, Richard Bellman, purposely chose the name "Dynamic Programming" because it sounded impressive and non-mathematical so that he'd be more likely to get government funding. I don't understand why you would use memoization for fibonacci ever and hence its relevance for dynamic programming. It can be solved with a tail recursive function with three input parameters. Solution left to the reader as an exercise. But how to you systematically deduce the tail recursion version?I feel like, in this case, the recursivity in definition of Fibonacci and the recursivity in the tail recursion is just a coincidence, with the second just being a contrived way to write the loop you get after applying dynamic programming and trimming the table to only the last two elements. I don't understand why you would use tail recursive functions for fibonacci ever and hence its relevance for dynamic programming. It can be solved with a simple equation with one input parameter.
2025-04-13Than or equal to 1, So it will return 1.Unwinding the StackNow, the recursive calls will start returning: After the 4th call now it will again start from back, returning to the Third Call first.Return to Third Call: factorial(2)We already have factorial(1) = 1, therefor factorial(2) will return, "2 * factorial(1)", that’s "2 * 1" , which returns as factorial(2) equals to 2.Return to Second Call: factorial(3)Now, factorial(2) is 2, therefore factorial(3) equals to "3 * 2", that’s 6.Return to Initial Call: factorial(4)We have factoria(3) which returns 6, therefore, factorial(4) returns "4 * 6 = 24".Types of RecursionRecursion can be categorized into two main types where each with its own sub-categories −1. Direct RecursionDirect recursion occurs when a function calls itself directly −Simple Direct RecursionThe function calls itself with a simpler or smaller instance of the problem. It is used for solving problems like factorial calculation, fibonacci sequence generation, etc.Tail RecursionA form of direct recursion where the recursive call is the last operation in the function. It is used for solving accumulative calculations and list processing problems.int factorial(int n, int result = 1) { if (n Head RecursionThe recursive call is made before any other operation in the function. Processing occurs after the recursive call returns. It is used for tree traversals and output generation.void printNumbers(int n) { if (n > 0) { printNumbers(n - 1); // Recursive call first cout Linear RecursionEach function call generates exactly one recursive call, forming a linear chain of calls. It is used for simple counting or summing.int linearRecursion(int n) { if (n 2. Indirect RecursionIndirect recursion occurs when a function calls another function, which eventually leads to the original function being called. This involves two or more functions calling each other.Mutual RecursionIn mutual recursion, two or more functions call each other in a recursive manner, forming a cyclic dependency. It is used for even and odd number classification and grammar parsing.#include using namespace std;void even(int n);void odd(int n);void even(int n) { if (n == 0) { cout OutputEvenEvenNested RecursionThe nested recursion is a form of indirect recursion where a recursive function makes another recursive call inside its own recursive call. It is used for solving complex mathematical and algorithmic problems.#include using namespace std;int nestedRecursion(int n) { if (n > 100) { return n - 10; } else { return nestedRecursion(nestedRecursion(n + 11)); // Nested recursive calls }}int main() { cout Output91Advantages of RecursionSimplicity
2025-04-11Because it makes it extremely difficult to understand how to do the style of DP problems that involve filling out a 2D array.For example, look at the "best time to buy and sell stock" series on leetcode: are much more naturally done by filling out an array, right? I've never done them with a recursion; I can't say I've thought hard about it -- is there a natural recursive solution?(I linked to iii above but for anyone who hasn't tried them they are a great intro to DP problems; start with the first one: The point is that you don't have to exactly fill the 2D array to solve the problem in that way. The 2D array is an optimization in this view, and can be safely replaced with a cache without breaking the correctness. Of course there is also some learned techniques specific to dynamic programming, and that makes it worthy to learn at some point because otherwise you will never think of them, but at its core dynamic programming is just a specific way of doing recursion. OK, but, those are solved in just a few lines of code with 2D arrays. I'm not convinced it's helpful to approach them as recursions.Also, anyone who thinks they understand how to solve DP problems on leetcode because they understand how to memoize a fibonacci recursion is in for a rather large disappintment. I agree with that article that recursion is better introduced with relevant data structures than with Fibonacci. And I agree that Fibonacci is also too simple to explain dynamic programming, which is why I showed how it works with edit distance, and they with AoC 2023-12-18. > DP algorithms are "just" clever ways to cache a recursionIt does't work all the time like that since caching increases the
2025-03-27