1
\$\begingroup\$

I'm trying to solve this problem. After a couple of tries, this is what I pulled off:

 #include<stdio.h>
 #define primeLimit 100000
 int prime (long int Start2, long int Stop2 )
 {
 long int a[primeLimit+1];
 long int i,j,k,l;
 for (i=Start2;i<=Stop2;i++)
 {
 a[i-Start2] = 1;
 }
 for (i=Start2;i<=Stop2;i++)
 {
 if (a[i-Start2]!= 0 && i!=1)
 {
 for (j=3; j*j< i;j=j+2)
 {
 if(i%j==0)
 break;
 }
 if(j*j > i)
 {
 printf(" \n %ld",i);
 l = i;
 if (i<=46340)
 {
 for (k = i*i; k< Stop2;)
 {
 while (k<46340 && (k-Start2 <100000))
 a[k-Start2] = 0;
 k = k+l;
 }
 }
 }
 else
 {
 a[i-Start2] = 0;
 }
 }
 }
 return 0;
 }
 int main (void)
 {
 long int start,stop,a,look;
 scanf("%ld", &look);
 for (a=1;a<=look;a++)
 {
 scanf("%ld %ld", &start,&stop);
 prime (start,stop);
 }
 return 0;
 }

Here I used if (i<=46340) because the 46340*46340 exceeds the limit of a long int on a 32-bit machine (2,147,483,647). For the same purpose, I used while (k<46340 && (k-Start2 <100000)).

This code exceeds the time limit (6 seconds) of the SPOJ problem rule.

How can this be faster?

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jan 19, 2013 at 4:13
\$\endgroup\$
3
  • \$\begingroup\$ You should use the 'Segmented Sieve' algorithm. If you need the complete explanation of the problem look here: zobayer.blogspot.de/2009/09/segmented-sieve.html \$\endgroup\$ Commented Feb 18, 2013 at 15:19
  • \$\begingroup\$ cat_baxter, why should anyone look at that horrible code? Post it for review to find out all the things that are wrong with it. \$\endgroup\$ Commented Nov 11, 2014 at 16:55
  • 1
    \$\begingroup\$ @DarthGizka: That wouldn't be recommended as it's someone else's code. \$\endgroup\$ Commented Nov 11, 2014 at 16:58

1 Answer 1

2
\$\begingroup\$

The short answer: restrict your sieving to what is necessary (sieve potential factors up to the square root of the upper end of the range, sieve the range itself). The runtime for that is a few milliseconds, compared to several seconds (or even minutes) for sieving all numbers up to the upper end of the range.

An extensive answer with all the bells and whistles is at StackOverflow, where the SPOJ PRIME1 question has already been asked and answered:

How do I efficiently sieve through a selected range for prime numbers?

In addition to what is said there: trial division is the slowest form of primality test ever. The Sieve of Eratosthenes is equally simple but it is the fastest of them all, for small numbers up to 2^64 or thereabouts. Special requirements like that of SPOJ PRIME1 require small complications - e.g. windowed/segmented operation - and there are many complications that can be added to make it even faster if that is desired. See the linked article. However, for SPOJ I would keep things sweet and simple.

answered Nov 11, 2014 at 16:40
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.