Unkown error

I am trying to make a program that finds the smallest number with the most divisors,which is the number of divisors and how many numbers with that many divisors are.But there seems to be a problem with the line 26 and I can't figure out what it is.Please can someone help me?
Here is the code:

1 #include <fstream>
2 #include <iostream>
3 using namespace std;
4
5 int main()
6 {
7 int c[10000],d,r=0,nrdiv=0,contor=1,m;
8 long int a,b,min,i,e,nr;
9 ifstream f ("maxd.in");
10 ofstream g ("maxd.out");
11 f>>a;
12 f>>b;
13 for(i=2;i<=b/2;i++)
14 {d=2;
15 while((i>0)&&(i%d!=0)) d++;
16 if(i==d) {c[r]=i; r++;}}
17
18
19
20 for(i=a;i<=b;i++)
21 {nr=i;
22 e=0;
23 d=2;
24 for(e=0;nr!=1;)
25 {
26 if(nr%c[e]==0) {d++; nr/=c[e];} //here is the problem
27 else {c++;}
28 }
29
30 if(d==nrdiv) {contor++;}
31 if(nrdiv<d) {min=i; nrdiv=d; contor=1;}
32 }
33 g<<min<<" "<<nrdiv<<" "<<contor;
34
35
36 f.close();
37 f.close();
38 }
39
put your code in code tags:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
    int c[10000],d,r=0,nrdiv=0,contor=1,m;
    long int a,b,min,i,e,nr;
    ifstream f ("maxd.in");
    ofstream g ("maxd.out");
    f>>a;
    f>>b;
    for(i=2;i<=b/2;i++)
    {
         d=2;
         while((i>0)&&(i%d!=0)) d++;
          if(i==d) {c[r]=i; r++;}
     }
     for(i=a;i<=b;i++)
     {
          nr=i;
          e=0;
          d=2;
         for(e=0;nr!=1;)
        {
             if(nr%c[e]==0) {d++; nr/=c[e];} //here is the problem
             else {c++;}
         }

         if(d==nrdiv) {contor++;}
         if(nrdiv<d) {min=i; nrdiv=d; contor=1;}
     }
     g<<min<<" "<<nrdiv<<" "<<contor;

     f.close();
     f.close();
}


It makes it easier to read.
That being said, I can't help you, sorry.

EDIT: I don't know, but maybe try making everything ints and not those random long ints. I think the modulus wants two of the same type. Like int % int. You were doing int % long. Just a thought
Last edited on
else {c++;}
The above line is not valid. You can not increment arrays as pointers. If you need to stroll in some array using pointer arithmetic, then you have to use a pointer.

For example:
int* d = c; and then use d to move around the array.

Regards

EDIT: Sorry you use the d identifier already, but you can use another name, say ptr or something meaningful.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <fstream>
#include <iostream>
using namespace std;

int main()
{
    int c[10000],d,r=0,nrdiv=0,contor=1;
    long int a,b,min,i,e,nr;
    ifstream f ("maxd.in");
    ofstream g ("maxd.out");
    f>>a;
    f>>b;
    for(i=2;i<=b/2;i++)
    {d=2;
    while((i>0)&&(i%d!=0)) d++;
    if(i==d) {c[r]=i; r++;}}



    for(i=a;i<=b;i++)
    {nr=i;
     e=0;
     d=2;
         for(e=0;nr!=1;)
         {
             if(nr%c[e]==0) {d++; nr/=c[e];}
             else {e++;}
         }
        if(d==nrdiv) {contor++;}
        if(nrdiv<d)  {min=i; nrdiv=d; contor=1;}
    }
 g<<min<<" "<<nrdiv<<" "<<contor;


    f.close();
    f.close();

}

It was e not c, my bad :(.Sorry for the miss write.
Ok, I get the code. You find the primes, you divide by the primes to find the number of divisors, etc. There is semantic error (the math logic), but before I start rambling I would like to know if the problem is technical. Is it some segmentation fault or something like that, or is the result you get wrong? And do you count the prime divisors or all divisors?
I count only the prime divisors, and the problem is technical, i don't even get a result out of it.
First, the prime divisors here are counted with their multiplicities. That is, if some number has a factor 25, 5 will be counted twice.
To solve this (i.e. count 5 only once), substitute the line:
if(nr%c[e]==0) {d++; nr/=c[e];}
with the lines
1
2
3
4
5
            if(nr%c[e]==0)
            {
                d++;
                do {nr/=c[e];} while(nr%c[e]==0);
            }

Second, if some number is prime, then it will have no prime divisors other than itself. Consequently, you will exhaust all of the c array, and nr will still be at its original value (still != 1). But since there is no guarding condition, you will not stop trying to factor nr, and you will move e past the end of c, and continue trying with the junk numbers there. This will also lead to a segmentation fault or to a division by zero. To solve this, substitute the line:
else {e++;}
with the line
1
2
3
4
5
            else
            {
                e++;
                if (e==r) break;
            }

I see that before factoring each number, you initialize the number of divisors to 2 (d=2;). This assumes that every number starts with two prime divisors: 1 and the number itself. But if the number is not prime, then it is error to include is as prime divisor. To correct this, initialize the number of divisors to 1 (d=1;). Then, after the loop that factors the number, check to see if the number of divisors is still 1. If it is, then this number is prime, and therefore the number itself is also prime (albeit trivial) divisor of itself. So you can add the line:
if(d==1) {d=2;}

In summary, the code with my modification (consistent with your coding style) looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
using namespace std;

int main()
{
    int c[10000],d,r=0,nrdiv=0,contor=1;
    long int a,b,min,i,e,nr;
    ifstream f ("maxd.in");
    ofstream g ("maxd.out");
    f>>a;
    f>>b;
    for(i=2;i<=b/2;i++)
    {
        d=2;
        while((i>0)&&(i%d!=0)) d++;
        if(i==d) {c[r]=i; r++;}
    }

    for(i=a;i<=b;i++)
    {
        nr=i;
        e=0;
        d=1;

        for(e=0;nr!=1;)
        {
            if(nr%c[e]==0)
            {
                d++;
                do {nr/=c[e];} while(nr%c[e]==0);
            }
            else
            {
                e++;
                if (e==r) break;
            }
        }

        if(d==1) {d=2;}
        if(d==nrdiv) {contor++;}
        if(nrdiv<d)  {
            min=i; nrdiv=d; contor=1;
        }
    }

    g<<min<<" "<<nrdiv<<" "<<contor;

    f.close();
    g.close();
}


Regards

P.S.: I also don't see the purpose of that (i > 0) in the prime search loop.
Thx allot simeonz you helped me so much.
Topic archived. No new replies allowed.