I have a program that prompts the user to enter up to 10 digits. The program then uses a function to return the sum of the divisors of each number entered minus itself and display it until that number is equal to 1 or 0. My problem is that the function stops after 45's divisors are summed. I'm trying to use recursion here because the function will be called 'n' number of times until each one is equal to 0 or 1. What makes recursion so useful in situations like these and how can I apply it here? Is there something i'm missing about the way this function is called? Can someone help me?
For example,
if the user types: 25 -4 6 45 (then presses enter)
the program should output:
25 1 0
-4 0 0
6 6
45 33 15 9 4 3 1 0 0
6 is an example of a perfect number and will repeat, so if a perfect number occurs it should stop summing the divisors. When the sum is equal to 0 is should print once and then stop. Also -4 is out of range so it should also print 0. Must be greater than 1.
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
//Fields
int i=0, j=0, k=0, l=0, num = 0, x = 0, count = 0, total = 0, z = 0;
signed int b[11] = {0};
char discard;
//Prompt message
printf( "\n\nPlease enter your list of numbers: " );
//This while loop scans until the enter button is pressed
while(i < 11 && (scanf("%d%1[^\n]s", &b[i], &discard)) == 2)
{
++count;
i++;
}
puts("");
puts("");
//Display Factors
while(k <= count)
{
x=b[k];
num = sum_divisors(x);
printf("%d " , num);
k++;
puts("");
}
}//End of main
//function to sum the divisors together
int sum_divisors(int a)
{
int total = 0;
int z = 0;
printf("%d ", a);
if(a < 1)
{
total = 0;
}else
{
if((a%1 == 0) && a !=1)
total = total + 1;
for(z=2; z<102; z++)
{
if((a%z == 0) && a != z)
{
total = total + z;
}//if
}//for
}//end if/else statement
// printf("%d ", total);
return total;
}//end function sum_divisors
First, I just wanted to mention a few things, the first being that the statement a % 1 == 0
is always going to be true for any positive integer a
, and so it should not be used in a conditional, the other is that you should try avoid using magic
numbers, such as 102
in the for loop in sum_divisors
; There is a more natural, and general value that could be used to replace 102
, and I imagine using such a constant would cause more grief with larger numbers whose divisors larger than 102 would not be calculated.
That being said, the way you've structured sum_divisors
is pretty close to how it should be, accept it is missing the recursive call and so only a few changes need to be made to make it recursive.
sum_divisors
return a value (accept possibly the number of times it recurred), so a return value of void
seems more appropriate.lets get rid of that (a%1==0)&&(a!=1)
and change the base case to.
if( a <= 1 )
return;
so that the function knows when to stop
102
with a-1
in order to omit counting a
as a divisor, instead of the a!=z
sum_divisors( total );
another thing would be to initialise total such that total = 1
,so we don't need to treat a=1
as an exception to the base case.
after everything is said and done, this is what's left
void sum_divisors( int a )
{
int total = 1; // divisor sum of a
int z;
printf("%d ", a); // print value
if( a <= 1 ) // base case
return;
for( z = 2; z < a-1; ++z) // z < a-1 as to not include a in total
{
if( a%z == 0 )
{
total += z;
}
}
if( total == a ) // a is a perfect number so we're done
return;
sum_divisors( total ); // call sum_divisors recursively with a = total
}
It's not much different from what you had initially
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With