Why does this incorrect memoized fibonacci function work? - c

Here's an incorrect implementation of memoized fibonacci:
long int fib(int n) {
long int memo[100];
if(n<2) {
return n;
}
if(memo[n] != 0) {
return memo[n];
}
else {
memo[n] = fib(n - 1) + fib(n - 2);
return memo[n];
}
}
It is incorrect because the array memo is a brand new array each call and no memoization is occuring. The easiest fix is to make memo static. But, lo and behold, the code works!
I stepped through it in the debugger and memo is behaving as if it was static! It appears that the compiler generated code that is placing memo in the same memory space at every call as opposed to new fresh memory. Why is that?
Compiler used is Apple clang version 11.0.0 (clang-1100.0.33.12).

It is UB, but if we assume that stack of a fresh thread contains only zeroes,
then all values in memo[100] can be zeroes or remains of previous call of the function.
The effective algorithm might work like the following:
long int memo[100] = {0};
long int fib(int n) {
if(n<2) {
return n;
}
if(memo[n] != 0) {
return memo[n];
}
else {
memo[n] = fib(n - 1) + fib(n - 2);
return memo[n];
}
}
Except each layer of recursion have own 'memo[100]'.

Related

Is there a better way to exit all recursive functions at once, rather than one by one?

Is there a better way to exit all of the recursive iterations immediately after the if(a == b) condition is met, instead of having to include lines 7 and 8 in their current form? Without lines 7 and 8 as they currently are, it seems to exit merely the last iteration.
bool recursive(int a, int b) {
if(a == b)
return true;
for(int i = 0; i < count; i++)
if(locked[b][i] == true)
if(recursive(a, i) == true)
return true;
return false;
}
It's not really critical, but I'd like to spare lines whenever possible. Any ideas?
I would probably write this like so:
bool recursive(int a, int b) {
bool result = (a == b);
for (int i = 0; i < count && !result; i++) {
result = (locked[b][i] && recursive(a, i));
}
return result;
}
Introduction of a variable to hold the working result of the function allows for testing that result as part of the condition for performing a loop iteration. That way you can terminate the loop as soon as the result flips from false to true, yet you don't need any code to distinguish after the fact between the two possible reasons for loop termination.
Yes. You could use a bit obscure functionality of C named longjmp.
It allows to jump back a stack over multiple function calls. A bit similar to throw in C++.
Firstly, return environment is created with setjmp().
It returns 0 if to was a first call to setjmp().
Otherwise it returns a value set by longjmp() called deeper in the recursive call.
#include <stdio.h>
#include <setjmp.h>
void slowrec(int n) {
if (n == 0) {
puts("done");
} else {
puts("go down");
slowrec(n - 1);
puts("go up");
}
}
jmp_buf env;
void fastrec(int n) {
if (n == 0) {
puts("done");
longjmp(env, 1);
} else {
puts("go down");
fastrec(n - 1);
puts("go up");
}
}
int main() {
puts("-- slow recursion --");
slowrec(5);
puts("-- longjmp recursion --");
if (setjmp(env) == 0) {
fastrec(5);
}
return 0;
}
produces:
-- slow recursion --
go down
go down
go down
go down
go down
done
go up
go up
go up
go up
go up
-- longjmp recursion --
go down
go down
go down
go down
go down
done
For original problem the code may look like this:
jmp_buf env;
void recursive_internal(int a, int b) {
if (a == b) longjmp(env, 1); // true
for(int i = 0; i < count; i++)
if(locked[b][i])
recursive_internal(a, i);
}
bool recursive(int a, int b) {
if (setjmp(env) == 0) {
recursive_internal(a, b);
// left without triggering long jump
return false;
}
// returned with longjmp
return true;
}
Note that there is no return value in recursive_internal because either a==b condition is met and longjmp was taken as it was the only way true could be returned. Otherwise, condition was never met and the algorithm exited via return false.

Implementation of a double factorial tail-recursive function in C

I got stuck trying to implement the following formula in my C code:
N!! = N!/(N-1)!!
The code is supposed to be a tail-recursive function, and although it does work and the computation is correct, I'm pretty sure this is not a tail function + I really can't tell what's going on during the return stage.
My current code:
long long int Factorial(int n)
{
if (n < 0)
return 0;
if (n == 0 || n == 1)
return 1;
return (n*Factorial(n - 1));
}
int DoubleFactorialTail(int n, int fact)
{
if (n < 0)
{
return 0;
}
if (n == 0 || n == 1)
{
return fact;
}
else
{
long long int factorial = Factorial(n);
return (factorial / DoubleFactorialTail(n - 1, fact));
}
}
I know that a double factorial tail-recursive function is supposed to call the recursive function at the end and nothing else, but here what I did was divide it by value(recursive in this case), that's why I'm not so sure my implementation is correct.
EDIT:
I originally tried implementing the following:
long long int DoubleFactorialTail(int n, int fact)
{
if (n < 0)
{
return 1;
}
if (n == 0 || n == 1)
{
return fact;
}
else
{
return (DoubleFactorialTail(n - 2, fact*n));
}
}
and the result will be:
res = (Factorial(n)/DoubleFactorialTail(n-1, 1));
Thing is, we were told that for n<0, the function needs to return 0 and save it in res.
but this equation will have 0 in its denominator if I choose to proceed and implement it this way.
So I guess my main question is: Is there a way to write this code in a tail-recursion manner while keeping this criterion intact?
I know that a double factorial tail-recursive function is supposed to call the recursive function at the end and nothing else
This is true, so
return (n*Factorial(n - 1));
or
return (factorial / DoubleFactorialTail(n - 1, fact));
Is not going to work.
The pattern has to be literally
return CallToRecursive(args);
The reason is that a tail recursive optimization lets CallToRecursive(args); return to the caller of this function and does not add a frame to the call-stack.
If you add code that needs to further process the return value, then it needs a frame in the call-stack to hold the return value and return point, and that's not TCO.
The way to approach this is usually to pass along work in progress to the next call.
long long int FactorialTCO(int n, long long factSoFar)
{
if (n < 0)
return 0;
if (n == 0 || n == 1)
return factSoFar;
return FactorialTCO(n - 1, n * factSoFar);
}
long long int Factorial(int n) {
return FactorialTCO(n, 1);
}
Note that this line:
return FactorialTCO(n - 1, n * factSoFar);
Returns exactly what it gets back from the recursive call. This means the compiler does not need to make a new stack frame, and that call will return to this function's caller. As we do this multiple times, we can effectively jump all the way back to the first caller when we are done instead of unwinding the stack frame.
I leave the transformation of the double up to you or others.

C Program to calculate sum of numbers X to Y using recursion

I have below code which works fine.
#include<stdio.h>
int calculateSum(int);
int main() {
int num;
int result;
printf("Input number = ");
scanf("%d", &num);
result = calculateSum(num);
printf("\nResult from 1 to %d = %d", num, result);
return (0);
}
int calculateSum(int num) {
int res;
if (num == 1) {
return (1);
}
else {
res = num + calculateSum(num - 1);
}
return (res);
}
Input number = 5
Result from 1 to 5 = 15
Now I am trying to give the program 2 inputs, from and to numbers.
Example: first input = 5, second = 8 and result should be = 26 (5 + 6 + 7 + 8)
Any ideas of how to go about this? failing thus far.
int calculateSum(int fromNum, int toNum) {
int res;
if (fromNum == toNum) {
return (fromNum);
}
else {
res = fromNum + calculateSum((fromNum + 1), toNum);
}
return (res);
}
At the moment, you are hard-coding 1 as the terminating point of the recursion.
What you need is to be able to use a different value for that, and the following pseudo-code shows how to do it:
def calculateSum(number, limit):
if number <= limit:
return limit
return number + calculateSum(number - 1, limit)
For efficiency, if you break the rules and provide a limit higher than the starting number, you just get back the number. You could catch that and return zero but I'll leave that as an exercise if you're interested.
It should be relatively easy for you to turn that into real code, using your own calculateSum as a baseline.
I should mention that this is a spectacularly bad use case for recursion. In general, recursion should be used when the solution search space reduces quickly (such as a binary search halving it with each recursive level). Unless your environment does tail call optimisation, you're likely to run out of stack space fairly quickly.
Instead of stopping when you reach 1, stop when you reach from.
int calculateSum(from, to) {
if (to == from) {
return from;
} else {
return to + calculateSum(from, to-1);
}
}
change 1 to from:
int calculateSum(int from,int to) {
int res;
if (to== from) {
return (from);
}
else {
res = to+ calculateSum(from,to - 1);
}
return (res);
}
You can use ternary operator.
int calculateSum(int from, int to) {
return from == to ? from : from + calculateSum(from + 1, to);
}

How can I resolve this recursive overflow?

#define MIN -2147483648
long max(long x,long y)
{
long m=x;
if(y>x)
m=y;
return m;
}
long f(int x,int y,int **p)
{
long result;
if(x<0||y<0)
result = MIN;
else
if(x==0&&y==0)
result = p[0][0];
else
result = max(f(x-1,y,p),f(x,y-1,p))+p[x][y];
return result;
}
int main(void)
{
int n;
scanf("%d",&n);
int** p = (int **)malloc(n*sizeof(int*));
for(int i=0;i<n;i++)
{
p[i] = (int*)malloc(n*sizeof(int));
for(int j=0;j<n;j++)
scanf("%d",p[i]+j);
}
printf("haha\n");
printf("%ld\n",f(n-1,n-1,p));
return 0;
}
when I assign 10 to n, it works well.But when I assign 20 to n, there's no result put out. I googled it and I guessed that the error may be a recursive overflow. So how can I resolve this problem?
You're making a very large number of recursive calls. At each level, you make twice the number of calls as the prior level. So when N is 20, you're making 2^20 = 1048576 function calls. That takes a long time.
Most of these calls keep recomputing the same values over and over again. Rather that recomputing these values, calculate them only once.
Here's a non-recursive method of doing this:
long f(int x,int y,int **p)
{
long **p2;
int i, j;
p2 = malloc(sizeof(long *)*(x+1));
for (i=0;i<=x;i++) {
p2[i] = malloc(sizeof(long)*(y+1));
for (j=0;j<=y;j++) {
if (i==0 && j==0) {
p2[i][j] = p[i][j];
} else if (i==0) {
p2[i][j] = p2[i][j-1] + p[i][j];
} else if (j==0) {
p2[i][j] = p2[i-1][j] + p[i][j];
} else {
p2[i][j] = max(p2[i-1][j], p2[i][j-1]) + p[i][j];
}
}
}
return p2[x][y];
}
EDIT:
If you still want a recursive solution, you can do the following. This only makes recursive calls if the necessary values have not yet been computed.
long f(int x,int y,int **p)
{
static long**p2=NULL;
int i, j;
if (!p2) {
p2 = malloc(sizeof(long*)*(x+1));
for (i=0;i<=x;i++) {
p2[i] = malloc(sizeof(long)*(y+1));
for (j=0;j<=y;j++) {
p2[i][j] = MIN;
}
}
}
if (x==0 && y==0) {
p2[x][y] = p[x][y];
} else if (x==0) {
if (p2[x][y-1] == MIN) {
p2[x][y-1] = f(x,y-1,p);
}
p2[x][y] = p2[x][y-1] + p[x][y];
} else if (y==0) {
if (p2[x-1][y] == MIN) {
p2[x-1][y] = f(x-1,y,p);
}
p2[x][y] = p2[x-1][y] + p[x][y];
} else {
if (p2[x][y-1] == MIN) {
p2[x][y-1] = f(x,y-1,p);
}
if (p2[x-1][y] == MIN) {
p2[x-1][y] = f(x-1,y,p);
}
p2[x][y] = max(p2[x-1][y], p2[x][y-1]) + p[x][y];
}
return p2[x][y];
}
You don't specify which compiler you are using. Look into how to increase stack size for your program. However, even if you get it to work for n=20, there will be a limit (may not be far from n=20) due to combinatorial explosion as mentioned in previous comment.
For n > 0, each call to f(n) calls f(n-1) twice. So calling f(n) = calling 2*fn(n-1)
For n = 20, that is 2^20 calls. Each call returns a long. If long is 8 bytes = 2^3, then you have at least 2^23 bytes on the stack.
EDIT
Actually, according to the documentation, the linker controls the stack size.
You can try increasing stack size and implement more efficient algorithm as proposed by different answers
To increase stack size with ld (the GNU linker)
--stack reserve
--stack reserve,commit
Specify the number of bytes of memory to reserve (and optionally commit) to be used as stack for this program. The default is 2Mb reserved, 4K committed. [This option is specific to the i386 PE targeted port of the linker]

Star printing in C the hard way

I've started exercising some C and found this nice exercise where I have to print a triangle via input.
for the input 6 it will print
*
**
***
****
*****
******
*****
****
***
**
*
Now, looking at it I thought, well, that's not such a hard task. So I decided to try and write it using recursion, no loops and only 2 variables.
the function should looks like this:
void PrintTriangle(int iMainNumber, int iCurrNumber)
{
//Logic goes here
}
A few hours later I realized this is a lot harder than I thought, since I need to pass enough information for the function to be able to "remember" how much triangles it should print.
So now I decided to ask you if that is even possible.
(remember, no loops, no other functions, only recursion).
EDIT:
This isn't homework, this is out of sheer curiosity. However I probably can't validate for you.
I've managed to get halfway through with this
void PrintTriangle(int iMainNumber, int iCurrNumber)
{
if (iMainNumber == 0)
{
printf("\r\n");
}
else if (iMainNumber == iCurrNumber)
{
printf("\r\n");
PrintTriangle(iMainNumber - 1, 0);
}
else
{
printf("%s", MYCHAR);
PrintTriangle(iMainNumber, iCurrNumber + 1);
}
}
I got stuck trying to create the opposite function, I believe that if I could do it, I would be able to use the fact that iMainNumber and iCurrNumber are positive or negative to navigate through the functions flow.
In other words, when the parameters are negative I would print a descending star in the length of the input minus one, and when the parameters are positive I would print the ascending star in the length of the input.
I've thought about Using a flag, but not instead of 2 integers.
Maybe if I'd add another flag and have 2 integers and a flag then I could solve it, but as I said, I tried to limit myself to 2 integers.
What I'm starting to think is that there is no way to pass the information required to print an ascending star in this method without using more than 2 integers and recursion.
But I'm still not so sure about that, hence the question.
I came up with:
void PrintTriangle(int size, int indent)
{
switch(size) {
case 0:
if (indent > 1) PrintTriangle(size, indent-1);
putchar('*');
break;
case 1:
PrintTriangle(size-1, indent+1);
putchar('\n');
break;
default:
PrintTriangle(1, indent);
PrintTriangle(size-1, indent+1);
PrintTriangle(1, indent);
break; }
}
int main()
{
PrintTriangle(6, 0);
return 0;
}
as a quick first attempt. Seems to do the job.
size is the size of the triangle to print, and indent is the number of extra stars to print before each row of the triangle. size==0 means just print indent stars and no newline (used to print the indent before the triangle)
If you want something a bit more compact, you could rewrite this as:
void PrintTriangle(int size, int indent)
{
if (size <= 0) {
if (indent > 1) PrintTriangle(size, indent-1);
putchar('*');
} else {
if (size > 1) PrintTriangle(1, indent);
PrintTriangle(size-1, indent+1);
if (size > 1) PrintTriangle(1, indent);
else putchar('\n'); }
}
Anything done with loops can be done with recursion with the same number of variables. You just have to tease out what is the state, and pass that updated state in a recursive call, instead of looping.
So let's do it iterativey, first. The input is size, the size of the triangle. Let's have two state variables, lineNumber from 1 to size*2-1 and columnNumber from 1 to size. Note that:
columnsForLine = lineNumber <= size ? lineNumber : size*2 - lineNumber
The iterative version would be like this:
int lineNumber = 1;
int columnNumber = 1;
int size = 6;
while (lineNumber <= size*2-1) {
printf("*");
int columnsForLine = lineNumber <= size ? lineNumber : size*2 - lineNumber;
if (columnNumber == columnsForLine) {
printf("\n");
columnNumber = 1;
lineNumber += 1;
}
else {
columnNumber += 1;
}
}
That does indeed work. Now how to do it recursively? Just tease out where state is being updated and do that as a recursive call:
void recstars(int size, int lineNumber, int columnNumber) {
if (!(lineNumber <= size*2 - 1)) {
return;
}
printf("*");
int columnsForLine = lineNumber <= size ? lineNumber : size*2 - lineNumber;
if (columnNumber == columnsForLine) {
printf("\n");
recstars(size, lineNumber + 1, 1);
}
else {
recstars(size, lineNumber, columnNumber + 1);
}
}
recstars(6, 1, 1);
And voila. Works for any size, e.g. 13.
Note that the code is basically the same, it's just a matter of doing the control flow differently. Also note that this is tail-recursive, meaning a smart compiler would be able to execute the recursive calls without growing the stack for each call.
Hmm if you only want to use 2 variables though, including the input, will be a bit trickier... you can always cheat and stuff all 3 integers into one integer, then unpack it & re-pack it each time. e.g.
void recstars(int state) {
int size = state / 10000;
int lineNumber = (state - size*10000) / 100;
int columnNumber = state - size*10000 - lineNumber*100;
if (!(lineNumber <= size*2 - 1)) {
return;
}
printf("*");
int columnsForLine = lineNumber <= size ? lineNumber : size*2 - lineNumber;
if (columnNumber == columnsForLine) {
printf("\n");
recstars(size*10000 + (lineNumber+1)*100 + 1);
}
else {
recstars(size*10000 + lineNumber*100 + (columnNumber+1));
}
}
recstars(6*10000 + 1*100 + 1);
Seems to work. Is that legit, you think?
Otherwise, the tricky part isn't the recursion, it's just getting the job done with only 2 ints for state. Can you do it iteratively with only 2 integers?
Using 2 parameters as OP suggested
void PrintTriangle(int iMainNumber, int iCurrNumber) {
if (iMainNumber < 0) { // Row (use negative iMainNumber)
printf("%c", '*');
PrintTriangle(iMainNumber + 1, 0);
if (iMainNumber == -1)
printf("\n");
} else if (iMainNumber > 0) {
if (iCurrNumber < iMainNumber) { // Preceding short lines
if (iCurrNumber > 1)
PrintTriangle(iMainNumber, iCurrNumber - 1);
PrintTriangle(-iCurrNumber, 0);
} else if (iCurrNumber == iMainNumber) {
PrintTriangle(iMainNumber, iCurrNumber - 1); // left
PrintTriangle(iMainNumber, iCurrNumber + 1); // Right
} else { // Subsequent short lines
if ((iCurrNumber - iMainNumber) < iMainNumber)
PrintTriangle(iMainNumber, iCurrNumber + 1);
PrintTriangle(-(iCurrNumber - iMainNumber), 0);
}
}
}
int main() {
PrintTriangle(3,3);
PrintTriangle(6,6);
return 0;
}
From what I have read, most suggestions have already pointed out to pass in any state you need.
However, you really don't need that many branching statements. Most of what you need, you can derive arithmetically. You can calculate the total number of recursions and derive the number of stars from the current recursion count. Also, by separating the portion of the initial invocation from the recursion, you can make usage much simpler.
Just saw that you do not want more than two integers. Consider the below and see if you really want to maintain that preference. If so, you can put the calculation of the total in the recursive portion. I think it would be less readable.
void _print_stars(int height, int total, int current)
{
int stars = current <= height ? current : 2 * height - current;
for (int i = 0; i < stars; i++) { printf("*"); }
printf("\n");
if (current != total)
{
_print_stars(height, total, current + 1);
}
}
void print_stars(int height)
{
int total_recursions = 2 * height - 1;
_print_stars(height, total_recursions, 1);
}
Pure recursion, no loops, calling program 'main()' passes only one parameter:
void PrintTheClms(int width, int stars) {
printf("*");
if stars < width then {
PrintTheClms(width, stars+1);
}
}
void PrintStars(int width) {
PrintTheClms(width, 1);
printf("\n");
}
void PrintTheRows(int size, int indent) {
PrintStars(indent);
if indent < size then {
PrintTheRows(size, indent+1);
PrintStars(indent);
}
}
void PrintTriangle(int size) {
if size > 0 then {
PrintTheRows(size, 1);
}
}
int main() {
PrintTriangle(6);
PrintTriangle(11);
// etc.
return 0;
}
Very simple -- no else clauses, no case constructs, no direction flag. Lots of procs and lots of calls, though.

Resources