Collatz chain recursive function C - c

I am trying to create some code that when given a starting number attempts to find the length of the corresponding collatz chain.
I was hoping to do this recursively and this is what I have so far :
#include stdio.h
int collatz(int number, int count)
{
if(number == 1)
{
return count;
}
if(number%2==0)
{
number = number/2;
collatz(number, count+1);
}
else
{
number = number*3+1;
collatz(number,count+1);
}
return 0;
}
int main(void)
{
int stored=0;
int temp;
for(int i = 1;i<10;i++)
{
temp = collatz(i,1);
if(temp>stored)
{
stored = temp;
}
}
printf("%i\n",stored);
}
The problem is of course that the function eventually reaches its endpoint, but then gets returned as the length of the chain and this becomes the new number..
How can I structure this program so that when the count reaches its endpoint I can take this value as the output of the very first call?

You need to return the result of the recursive call. Right now you're ignoring the value of the recursive call and returning 0. Each recursive call should look like this:
return collatz(number, count+1);

Related

why is this recursive function doesn't return 'counter' value?

int rec(int k)
{
static int temp = 0, counter = 0;
if(!k) return counter;
if(k%2 == 0){
counter++;
temp = rec(k/2);
}
if(k%2){
counter++;
temp = rec(k-1);
}
}
This function is supposed to get a number k and check how many operations are needed to get k to 0 only by multiplying by 2 or by adding 1.
this function works fine but returns zero instead of the last value in the counter. I tried to debug it, and I saw the counter value increasing, but after getting to the value it is supposed to return, the function goes back to complete all the calls, and returns 0.
I fixed it by making counter global and returning nothing, but my questions are:
Is there a way to fix it as it is with the counter inside the function?
Why is this function returning zero at the end?
Here's a nice recursive function that doesn't declare any variables at all, it's purely recursive!
int get_steps_to_zero(int n)
{
// Deal with negative values
if (n < 0) n *= -1;
if (n == 0) {
// Base case: we have reached zero
return 0;
} else if (n % 2 == 0) {
// Recursive case 1: we can divide by 2
return 1 + get_steps_to_zero(n / 2);
} else {
// Recursive case 2: we can subtract by 1
return 1 + get_steps_to_zero(n - 1);
}
}
get_steps_to_zero(457);
> 13
Others have addressed the general recursion issue, yet there remains a ...
Corner case
"this function works fine" --> Not quite.
The algorithm is an infinite loop for rec(-1) as it attempts -1 --> -2 --> -1 --> -2 ...
A better approach would sometimes add 1.
if(k%2) {
counter++;
// temp = rec(k-1);
temp = rec(k + (k < 0 ? 1 : -1));
}
This also well handles non-2's complement issue.
I will try to show a new side to this discussion,
Recursion is like a chain,
This means that any function can receive a value from its child and return a value to its parent.
In your program you are trying to return a value from the last child to the first parent,
So your program must have all links in the chain receive and send value in order.
But in your code you return a value only in the last call, and all other calls do not return this value back.
Your stop condition is here:
if(!k) return counter;
Only the last call enters this scope, but other calls do not reach any return statement.
they get to here:
if(k%2 == 0){
counter++;
temp = rec(k/2);
}
if(k%2){
counter++;
temp = rec(k-1);
here there is no return statement.
your compiler will warning you like this:
"warning: control reaches end of non-void function".
but your program will compile so it return zero like all non-void functions without return.
So if you want this program to work make it like Randomblock1, or like this:
int rec(int k)
{
static int counter = 0;
if(!k){
return counter;
}
else if(k%2 == 0){
counter ++;
counter += rec(k/2);
}
else{
counter++;
counter += rec(k-1);
}
return counter;
}
But this program also do not work well, what is the reason?
The reason is because you used by static variable.
It's a little hard to explain, but you can't use this recursion with a static variable, so add a patch to this line:
static int counter = 0;
like this
int counter = 0;
I hope what I wrote will be understandable

Program that computes the nth element of a number series given by a formula

Write a method/function with name cpSeries that computes the nth element in a series of numbers, given by the formula: a(n) = (a(n-1))2+a(n-2) when: n>1 and assuming that: a(1)=1, a(0)=0 Note that indexing of the series starts from 0.
I have already written the above code but it runs for an infinite time and I don't know how to fix it in order to compute the nth element.
Any ideas? I have to use only functions to solve this problem.
# include <stdio.h>
int cpSeries(int n)
{
int Nthterm = 0;
int i;
if (n==0) {
cpSeries(0) == 0;
}
else if (n==1) {
cpSeries(1) == 1;
}
for (i=0; i<=n; i++){
Nthterm = cpSeries((n-1))*cpSeries((n-1)) + cpSeries((n-2));
return Nthterm;
}
}
int main()
{
int n=6;
printf("The Nth term of the series is: %d",cpSeries(n));
}
If the provided equation gives you the nth element, I don't see the need for a loop.
Also, in the if conditions, you are calling the function again, but what you should do is return the value you need.
int cpSeries(int n){
int Nthterm;
if (n==0){
Nthterm = 0;
}
else if (n==1){
Nthterm = 1;
}
else {
Nthterm = cpSeries((n-1))*cpSeries((n-1)) + cpSeries((n-2));
}
return Nthterm;
}
Your final conditions just call the function another time instead of returning 0 or 1.
instead of
if (n==0) {
cpSeries(0) == 0;
}
else if (n==1) {
cpSeries(1) == 1;
}
use
if (n==0) {
return 0;
}
else if (n==1) {
return 1;
}
C is not a declarative language where you can specify the return value y of a function f given an argument x by writing something like f(x) = y, but you have to use a return statement.
Change cpSeries(0) == 0; to
return 0;
to avoid the infinite recursion (and the same for n == 1).

Recursion code it not working properly what can be the issue here?

Tried a program which prints the first 50 natural number I wrote this code which returns the value using recursion but its not printing anything not returning any values what m I doing wrong here?
#include <stdio.h>
int naturalNumbers(int i)
{
if (i == 1)
{
return 1;
}
else
{
naturalNumbers(i--);
return i;
}
}
int main()
{
printf("%d", naturalNumbers(50));
return 0;
}
below recursion will print numbers in increasing order
void naturalNumbers(int i)
{
if(i<1) return; //base case
naturalNumbers(i-1);
printf("%d ", i);
}
naturalNumbers(50); // call from main function
To avoid creating an endless loop, you should modify your naturalNumbers function as follows:
int naturalNumbers(int i)
{
if (i == 1)
{
return 1;
}
else
{
naturalNumbers(--i);
return i;
}
}
This will decrement the value of i before calling naturalNumbers instead of afterwards as in your version. However, the return value of this original call will always be (i-1). Can you please explain a little bit more about the intent of this function?

Can't return the correct int in C

i'm using this function (quicksort algorithm) and im
trying to get the total relocations also. In order to collect as much statitics i can i have to execute the function many times using a for loop, so after the end of the algorithm i must make the static variable equal to zero after copying it to a non-static variable and return it. Instead i always get a 0 return.
Please help me to not get a 0 grade too :P Thanks
int quicksort(int left, int right, int *p)
{
static int staticrelocations=0;
int i,j,mid,x,temp,relocations;
if(left<right)
{
i=left;
j=right;
mid=(left+right)/2;
x=p[mid];
while(i<j)
{
while(p[i]<x)
i++;
while(p[j]>x)
j--;
if(i<j)
{
if(p[i]==p[j])
{
if(i<mid)
i++;
if(j>mid)
j--;
}
else
{
temp=p[i];
p[i]=p[j];
p[j]=temp;
staticrelocations++;
}
}
}
quicksort(left,j-1,p);
quicksort(j+1,right,p);
}
relocations=staticrelocations;
staticrelocations=0;
return relocations;
}
You recurse into quicksort(), and in the innermost invocation you set staticrelocations = 0 before returning its former value. However, in the outer quicksort(), you ignore the return value of the inner quicksort. The outer quicksort returns the zeroed staticrelocations. Instead, you should go like this:
int quicksort()
{
int relocs = 0;
/* function logic */
if (/*did a new relocation*/)
relocs++;
relocs += quicksort(); //inner quicksort recursively
return relocs;
}

error: control may reach end of non-void function

This error appeared to me when i was trying to compile a c file which contains a declaration of a linear search function
bool search(int value, int values[], int n)
{
// TODO: implement a searching algorithm
for(int d = 0;d<n;d++){
if(n<0){
return false;
}
else if(values[d]==value){
return true;
}
else{
return false;
}
}
}
What is wrong with my code? Please help.
Some problems with the code:
The method have a path that don't return anything, as commented, when parameter n = negative number or 0
The for-loop don't do anything, will only execute one time and exit for one of the conditions. It would only work correctly when the first element is the element searched, in any other case only check the first element and return (without correct info of present or not). Test with array int values[] = { 1, 2, 3, 4, 5 }; and search 3, your code would not found this value.
If you're searching for a specific value the code is:
bool search(int value, int values[], int n) {
for (int d = 0; d < n; d++) {
if (values[d] == value) {
return true;
}
}
return false;
}
The problem is the argument n passed to the function is n <= 0. The loop never executes and the function finishes without returning any value.
To fix it put the if(n <= 0) statement before the for loop.
If the 'for' loop doesn't get to do any iterations you won't be able to return anything from the function. Maybe add an edge case like
if(n <=0 )
return false;
before the loop.
d is incremented in the for loop until it equals the value of n. At that point, the code beyond the for loop is executed.
Being that there are no instructions beyond the for loop, the function returns to the caller. The error occurs due to there being no (boolean) value returned from the function in this case.
The error can be avoided by following Rule #1 of the Mahonri List Of Rules For Writing Maintainable C Code. Example:
bool search(int value, int values[], int n)
{
bool rCode=false;
// TODO: implement a searching algorithm
for(int d = 0;d<n;d++)
{
if(n<0)
{
goto CLEANUP;
}
else if(values[d]==value)
{
rCode=true;
goto CLEANUP;
}
else
{
goto CLEANUP;
}
}
CLEANUP:
return(rCode);
}

Resources