# Thread: Why isn't this working?

1. ## Why isn't this working?

Hi guys, I wrote up a long program that pretty much works. What it does is when the user enters a string like 4,100 the program prints out all the prime,perfect and amicable pairs in that range.

Trouble is, I got the prime and perfect numbers to work but I'm having a bit of difficulty getting the amicable pairs.

Here is part of the code in main where the numbers from the user gets passed to the findAmicable method.

Code:
```while (1) {

printf("Enter a command: ");

fgets(command, sizeof(command), stdin);
command[strlen(command) - 1] = '\0';

if (sscanf(command, "%d,%d", &A, &B) == 2) {
int i;
for (i = A; i < B; i++) {
findAmicable(i);
}
}
}```
And here is the sum of the factors method and the findAmicable methods:

Code:
```int sumDiv(int number) {

int i;
int sum = 0;
for (i = 1; i <= number; i++) {
if(number % i == 0)
sum += i;
}
return sum;
}

void findAmicable (int number) {
int i;
int j;
for (i = 1; i <= number; i++) {
for (j = 1; j >= number; j--) {
if ((sumDiv(i) == j) && (sumDiv(j) == i) &&(i!=j)) {
printf("%d and %d are amicable numbers. \n", i, j);
}
}
}
}```
Help please? I don't know where the code is wrong.

2. I don't know what an amicable number is (sorry didn't look it up...)

Code:
```
for (i = 1; i <= number; i++) {
for (j = 1; j >= number; j--) {
...```

The 'j' loop seems to never fire unless number is negative? but then the 'i' loop won't in that case. Is this what you want?

3. Hi Watabou. Looking at your sum of factors (sumDiv), it appears to be more of a sum of numbers. Somewhere in that function, shouldn't you determine if a value is a factor of "number" before you add it to the sum?

Kevin

4. Originally Posted by kmess
Hi Watabou. Looking at your sum of factors (sumDiv), it appears to be more of a sum of numbers. Somewhere in that function, shouldn't you determine if a value is a factor of "number" before you add it to the sum?

Kevin
Oh whoops, maybe that's the problem. I'll see if that fixes it.

Oh and it's kinda hard to explain amicable numbers. One example is 220 and 284. They are amicable numbers since the factors of 220 add up to 284 and the factors of 284 add up to 220. So they form a pair.

I know there should be a better algorithm than what I'm doing. I've looked over some Euler's algorithms but that's confusing...

EDIT: Hmm, I changed the sumDiv method but it still won't work.
EDIT: Oh wait, what mike said makes sense. At first, I had it so that it accepted two parameters and I had to change it to one since the program guidelines state that.

I had the end point as the starting point for j so that's why it doesn't work as of now....
But then what can I do now?

5. No worries - I understand amicable numbers. That's probably the only reason I caught the sumDiv() issue. :P

Standing by...

Kevin

6. I looked more closely at your code, Watabou. You are testing for even divisibility (missed it in my haste) -- but here's a hint - you don't want to iterate from 1 to n. Let's take a look at a random number, say 220. The factors of 220 are 1,2,4,5,10,11,20,22,44,55, and 110. The sum of these is 284, which is the value we're expecting. Note that there is no reason to exceed n/2 in the loop (in fact, you don't need to exceed the square root of n, but there's another trick in that).

Kevin

7. Yeah you're right. I was actually planning on doing that later. It's what I used for prime and perfect numbers. I wanted to see what the program was actually doing in the debugger so I thought it would help having 1 to n here.

8. So, as for your findAmicable() function, let me draw your attention to something else. In theory, you're looking for all the amicable numbers in a range of 1 to whatever. So, we know you're going to have at least one loop. I would propose to you that you only need the one loop instead of two.

Let's say you have a number, n, and you want to find out if it is part of an amicable pair.

First, you need to know the sum of its factors, which you'll find from sumDiv(). You'll want to save this sum for later.
Code:
`int sum1 = sumDiv(n);`
Next, we want to start looking for another number that is the other half of an amicable pair. The most direct thing to do is to simply find the sum of factors of sum1 from above. If it is the same as n (the value we started with), we have our amicable pair!

Code:
`if (sumDiv(sum1) == n) ...`
If not, continue with the next iteration of the loop (and the next value of n).

See if that makes sense. If you can get this part working, then you can refine the code next.

Kevin

9. PS. I'm building this along with you as we talk about it. The results I have for 1..n..5000 are:
Code:
```\$ ./a.out
(6, 6)
(28, 28)
(220, 284)
(284, 220)
(496, 496)
(1184, 1210)
(1210, 1184)
(2620, 2924)
(2924, 2620)```
The refining I'm referring to is the elimination of reciprocal pairs (e.g. 220,284 and 284,220) and perfect numbers (e.g. 6 and 28).

10. Okay I'm a bit confused now.

So first I get all the factors of n and sum it. And that's sum1.

Then I make a loop to find the second number to go with it? How would I do that? Won't that be a infinite loop since it needs to check numbers greater than n?

11. No, you don't want a loop. Remember an amicable pair has the same sum of factors. Consider 220,284:
Code:
```sumDiv(220) == 284, AND
sumDiv(284) == 220```
If we find the sum of factors for a number, we need only compare that sum to the original number to see if it is an amicable pair (actually, without a little refining, we also get perfect numbers in the mix, but more on that later).

Pseudocode so far:
Code:
```for n in range(1..5000) do:
sum1 = sumDiv(n);
if sumDiv(sum1) == n:
We have two numbers whose sum of factors is equal!```
So, if n = 220, sum1 = sumDiv(220) , which is 284. sumDiv(sum1) = sumDiv(284) = 220, which is the original value of n. We have an amicable pair.

Kevin

12. Hmm okay so this is what I think you're saying:

Code:
```void findAmicable(int number) {
int sum1 = sumDiv(number);

if (sumDiv(sum1) == number) {
printf("%d %d\n", number, sum1);
}

}```
I mean it looks right. If I pass it 220, then sum 1 is 284. And the sumDiv of sum1 is 220 and when sumDiv(sim1) == 220 == number which is also 220, it should return it. But....it's not.

Every time I enter 0,300, it's giving me 0 1 and 1 1 for some reason.

That means my sumDiv method isn't correct?

13. Can you post your sumDiv() function again?

14. Yeah it's this:

Code:
```int sumDiv(int number) {

int i;
int sum = 0;
for (i = 1; i <= number; i++) {
if(number % i == 0)
sum += i;
}
return sum;
}```

15. That looks good as did your findAmicable() function. Can you show me how you're calling this (the loop), please?

Popular pages Recent additions