Magic in C recursion? who can explain? - c

Can somebody explain to me how this recursion works?
I'm getting stuck on how the result is 20 when the recursion leaves only on if a == b and it's a = 6 and b = 6
int main()
{
printf("%d \n",mistero(2, 6));
return 0;
}
mistero( a, b)
{
if( a == b ){
return a;
}
return a + mistero(a+1, b);
}

mistero(2, 6) =
2 + mistero(3, 6) =
2 + 3 + mistero(4, 6) =
2 + 3 + 4 + mistero(5, 6) =
2 + 3 + 4 + 5 + mistero(6, 6) =
2 + 3 + 4 + 5 + 6
= 20

Recursion works as below:
2 + mistero(3,6);
2 + 3 + mistero(4,6)
2 + 3 + 4 + mistero(5,6)
2 + 3 + 4 + 5 + mistero(6,6)
2 + 3 + 4 + 5 + 6 = 20

Just execute the code step by step and replace the function call by the return value.
When the function is first called :
return 2 + mistero(3,6);
mistero(3,6) returns 3 + mistero(4,6)
so the return statement eventually continues to get added till a==b
return 2+3+4+5+6

First your function definition has to be before your main, so that at compile time it is known in the main function otherwise you have to use a function prototype!
Also you forgot to define the return type and the types of the arguments. So your code should looks like this to work:
#include <stdio.h>
int mistero(int a, int b) {
//^ ^^^----^^^ variable type
//| Here return type
if( a == b ) {
return a;
}
return a + mistero(a+1, b);
}
int main() {
printf("%d \n",mistero(2, 6));
return 0;
}
Or with a function prototype:
#include <stdio.h>
int mistero(int a,int b);
int main() {
printf("%d \n",mistero(2, 6));
return 0;
}
int mistero(int a,int b) {
if( a == b ){
return a;
}
return a + mistero(a+1, b);
}
And this should show how it works:
return 2 + mistero(2 + 1, b);
return 2 + 3 + mistero(3 + 1, b);
return 2 + 3 + 4 + mistero(4 + 1, b);
return 2 + 3 + 4 + 5 + mistero(5 + 1, b);
return 2 + 3 + 4 + 5 + 6;
= 20

I am guessing the confusing aspect to this is the apparent lack of some sort of loop statement. I.e for or do while statement.
Think of it this way at the very end of the program.
return A + MISTERO(A+1, B) /* IS THE LOOP STATEMENT */
It causes the program to call the function MISTERO (A , B) from within the function MISTERO (A, B). So as long as this occurs you get a round about way of a loop. Until the loop is satisfied in the statement test if(A == B). Then the loop is escaped be a simple return A.
Thanks enjoy programming!!!

Related

Recursion: Collatz sequence -Could someone please explain how this code returns the total number of steps?

#include <cs50.h>
int collatz(int n);
int main(void)
{
int n = get_int("Enter int: ");
int steps = collatz(n);
printf("%i\n", steps);
}
int collatz(int n)
{
if (n==1)
{
return 0;
}
else if ((n%2)==0)
{
return 1 + collatz(n/2);
}
else
{
return 1 + collatz(3 * n + 1);
}
}
I am geting stuck trying to visualise how the 'return 1' on each iteration of the function gets 'carried through'.
I can write the steps out on paper to show that it does work, however I am struggling to make clear in my mind without going through step-by-step, why you have to +1 on every iteration of collatz.
This code:
if (n==1)
{
return 0;
}
says: If there are no steps to perform (because n is already 1), return zero.
Otherwise, this code:
else if ((n%2)==0)
selects one of the following:
return 1 + collatz(n/2);
or:
return 1 + collatz(3 * n + 1);
Each of those performs one step (either n/2 or 3 * n + 1) and then calls collatz to find out how many steps it takes to finish with that value. When collatz returns the number of steps needed for n/2 or 3 * n + 1, this code adds one for the step performed here. That gives the number of steps needed for n, which this code then returns.
Try to visualize it as follows:
starting number: 3
** collatz(3): return 1 + collatz(10); **
collatz(10): return 1 + collatz(5);
** collatz(3): return 1 + (1 + collatz(5)); **
collatz(5): return 1 + collatz(16);
** collatz(3): return 1 + (1 + (1 + collatz(16))); **
collatz(16): return 1 + collatz(8);
** collatz(3): return 1 + (1 + (1 + (1 + collatz(8)))); **
collatz(8): return 1 + collatz(4);
** collatz(3): return 1 + (1 + (1 + (1 + (1 + collatz(4))))); **
collatz(4): return 1 + collatz(2);
** collatz(3): return 1 + (1 + (1 + (1 + (1 + (1 + collatz(2)))))); **
collatz(2): return 1 + collatz(1);
collatz(1): return 0;
** collatz(3): return 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0; **

Adding Numbers Using Recursion In C

#include<stdio.h>
#include<conio.h>
int add(int n);
void main()
{
int n, ans;
clrscr();
printf("Enter Number:");
scanf("%d", &n);
ans = add(n);
printf("%d", ans);
getch();
}
int add(int n)
{
if (n==0)
{
return 0;
} else {
return n + add(n-1);
}
}
I have some doubts related recursion programs which have this type of return statements. Can anyone explain me it in a proper way.
I am not able to understand that thing if I am writing return 0 when n==0 then why it returns value from else.Why answer is not 0.I am confused in return statement.
Plz help me.
Thank You In Advance.
Lets take a simple example: add(2).
In that initial call we go to the else branch (because n is not zero) and do return 2 + add(2 - 1) (i.e. return 2 + add(1)).
That leads to the second calls, which also goes to the else branch and does return 1 + add(1 - 1) (i.e. return 1 + add(0)).
That leads to a call in which n is equal to zero and so we return zero.
That returns to the return 1 + add(1 - 1) part, which is equal to return 1 + 0 so return that.
That returns to the return 2 + add(2 - 1) part, which now is equal to return 2 + 1.
And that takes us back to the initial call, giving the result 3.
It can be laid out in a tree something like
add(2) -> return 2 + add(2 - 1)
add(1) -> return 1 + add(1 - 1)
add(0) -> return 0
add(1) -> return 1 + 0
add(2) -> return 2 + 1

Sum in C, from two numbers

Im creating a simple program in C that user insert a number, for example 5 and the program sums until 5, 0+1+2+3+4. Im using this formula
int sum_naturals(int n){
return (n-1)*n/2;
}
But now i want a formula that can sum from 2 different numbers, like user inserts number 5 and 9 and the program will do 5+6+7+8+9.
Can someone have ideia how can resolve this? Thanks
You can reuse your function
int sum(int a, int b) {
return sum_naturals(b) - sum_naturals(a-1)
}
Of course you have to add some validation.
Why not this?
int sum_2_naturals(int n, int m){
return (sum_naturals(m) - sum_naturals(n))
}
But now i want a formula that can sum from 2 different numbers,
To find the sum of a certain number of terms of an arithmetic sequence:
#include <stdio.h>
static int sum_naturals(int a, int b)
{
return ((b - a + 1) * (a + b)) / 2;
}
int main(void)
{
printf("%d\n", sum_naturals(5, 9));
return 0;
}
Output:
35
More info
Looks like a simple task, but since you still have problems understanding it, why don't you 'define' your functions first - before 'coding' them.
S(n) = 0 + 1 + 2 + ... + n-1 = n(n-1)/2
F(k,n) = k + k+1 + ... + n-1 + n = -(0 + 1 + ... + k-1) + (0 + 1 + ... + k-1) + k + k+1 + ... + n-1 + n = -S(k) + S(n) + n = S(n+1) - S(k)
Of course, need to assume that k <= n etc.
I guess the reason of all confusion is that you defined your basic function to sum from 0 to n-1, instead of 1 to n.

Not understand this recursive function that inverts digits of a number

I found this code
#include <stdio.h>
#include <math.h>
int rev(int num)
{
if(num < 10)
return num;
else
return (num % 10) * pow(10, (int)log10(num)) + rev(num/10);
}
int main(void)
{
printf("%d\n", rev(12345));
return 0;
}
And I set out to analyzing it, but now I have one doubt it is the following, to return to the starting point what values are obtained with (num % 10) according to my understanding should be (1,2,3,4,5) but when trying do the calculation manually I do not get the expected value.
What happens here, if someone explains to me this, or I missed out something?
int rev(int num) // num = 12345
{
if(num < 10) // false
return num;
else
return (num % 10) * pow(10, (int)log10(num)) + rev(num/10);
// (12345 % 10) * 10 ^ (log 12345) + rev(12345/10);
// 5 * 10 ^ (4) + rev (1234)
// 50000 + rev(1234)
}
Based on this, we can assume that:
rev(12345) = 50000 + rev(1234)
rev(1234) = 4000 + rev(123)
rev(123) = 300 + rev(12)
rev(12) = 20 + rev(1)
rev(1) = 1
So, the end result is:
rev(12345) = 50000 + 4000 + 300 + 20 + 1 = 54321
It is a simple math, the only non trivial rule is (int)log10(num), but it was explained by #QuestionC in his comment.

Summing two numbers recursively digit by digit in C

I need to write to recursive functions, where in the first one, I need to sum two integers digit by digit. I have written some code, but it gives me the final result multiplied by 10. I see that the problem happens because when I sum first two digits I multiply them by 10.
The second function must count number of carries in the sum. Meaning if two digits were 3 and 8, then when we sum them we get 11, which is result 1, and carry 1. Simply, I just need to count how many carries occur.
Please note that I assume that both numbers have same number of digits.
#include <stdio.h>
int sum(int a, int b)
{
int temp = (a%10) + (b%10);
static int mul = 1;
if(a == 0 && b == 0)
return 0;
else
{
mul *= 10;
return (mul*temp) + sum(a/10, b/10);
}
}
int carry(int a, int b)
{
static int counter = 0;
if((a%10) + (b%10) > 9)
counter++;
if(a == 0 && b == 0)
return counter;
carry(a/10, b/10);
}
int main()
{
int a = 1941;
int b = 2282;
int result = sum(a, b);
printf("%d\n", result);
int car = carry(a, b);
printf("%d\n", car);
return 0;
}
return (mul*temp) + sum(a/10, b/10);
Should be:
return temp + 10*sum(a/10, b/10);
You don't need a static variable, Static variables are used to implement a global state whose lifetime extent the entire process. That's not something desirable and should only be used at last resort. Furthermore, that's definitely not what you need here, using static variables to implement your solution will leads to functions that only work the first time they are called.
You should use the recursive property of your algorithm to aggregate the result:
int sum(int a, int b)
{
if(a == 0 && b == 0) {
return 0;
}
else
{
return (a%10) + (b%10) + 10*sum(a/10, b/10);
}
}
sum(1941, 2282) will expand to :
sum(1941, 2282)
1 + 2 + 10*sum(194, 228)
1 + 2 + 10*(4 + 8 + 10*sum(19, 22))
1 + 2 + 10*(4 + 8 + 10*(9 + 2 + 10*sum(1, 2))
1 + 2 + 10*(4 + 8 + 10*(9 + 2 + 10*(1 + 2 + 10*sum(0, 0))
1 + 2 + 10*(4 + 8 + 10*(9 + 2 + 10*(1 + 2 + 10*0)
You should use the same approach for carry :
int carry(int a, int b)
{
if(a == 0 && b == 0) {
return 0;
}
else if((a%10) + (b%10) > 9) {
return 1 + carry(a/10, b/10);
}
else {
return carry(a/10, b/10);
}
}
carry(1941, 2282) will expand to :
carry(1941, 2282)
0 + carry(194, 228)
0 + 1 + carry(19, 22)
0 + 1 + 1 + carry(1, 2)
0 + 1 + 1 + 0 + carry(0, 0)
0 + 1 + 1 + 0 + 0

Resources