So, long story short I have this HW about writing a recursive function in C that returns 0 or 1 based on if a given number is a perfect number or not (a perfect number is a number that is equal to the sum of its divisors example 6), I've managed to write a recursive function that calculates the Sum of a given number's divisors but in that case the output is the sum of the divisors not 0 or 1 and I have zero idea how to write a recursive function that returns 0 or 1 and at the same time calculate the sum of divisors and do the comparison. this is my code that outputs the sum of divisors :
#include<stdio.h>
int check(int n, int b ){
if (n==1) {return(1);}
if (b==1) {return(1);}
else if ((n % b) ==0) {
return (b check(n,(b-1)));
}
else
return(check(n,(b-1)));
}
void main() {
int n,res,b;
scanf("%d",&n);
if (n % 2==0) {b=n/2;} else {b=(n/2) 1;}
res=check(n, b);
printf("%d est un nombre %d",n,res);
}
CodePudding user response:
Notice that 1 is not a perfect number. The sum of all divisors when deciding if a number is perfect excludes the number itself. 0 is also not perfect, since perfect numbers have to be positive.
if (n < 2) return 0;
Assume the accumulated sum of divisors is passed into the function. Then, when you reach the stopping point, you return whether the sum is equal the number. To make this logic simple, the stopping point can be when your candidate divisor reaches 0.
if (b == 0) return sum == n;
Your recursive call will now check to see if your candidate divisor should be added to the sum.
assert(b > 0);
if ((n % b) == 0) sum = b;
return check(n, b-1, sum);
Implemented this way, the function becomes tail recursive. This would allow your recursive function to be optimized into a simple loop by a compiler that supports this optimization.
The initial call to your function would pass 0 in for the initial sum.
answer = check(n, n/2, 0);
In my own code, I would be tempted to define a helper function that only takes the single argument.
int check_if_perfect(int n) { return check(n, n/2, 0); }
This way, the caller wouldn't need to worry about the other arguments.
answer = check_if_perfect(n);