Search code examples
c++algorithmanalysis

Optimizating Prime Number Sequence


I am stuck on a questions from Codechef practice problems difficulty medium with problem statement:

Shridhar wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers

Rest of the description, I/O format, Test cases examples on this question link

The problem with my implementation is getting a TLE (Time Limit Exceeded) and wish to solve this problem, can you point out any problem in my implementation, I can't seem to figure it out after hours of dry run.

Includes, Directives and ifPrime function

#include<map>
#include<math.h>
#include<stdio.h>
#define LLD long long int
#define REPNE(i,a,b) for(LLD i=a; i<=b; ++i)
#define REPNEI(i,a,b,k) for(LLD i=a; i<=b; i+=k)
using namespace std;

map<LLD, bool> mem;

bool ifPrime ( LLD a ) {
    if ( a<2 ) return false;
    else if ( a==2 ) return true;
    else if ( a%2==0 ) return false;

    REPNEI(i,3,sqrt(a),2) {
        if ( a%i==0 ) return false;
    }

    mem[a] = true;
    return true;
}

Generate Prime Function

void genPrime ( LLD a, LLD b ) {
    REPNE(i,a,b) {
        if ( mem.find(i) != mem.end() ) printf("%lld\n", i);
        else if ( ifPrime(i) ) printf("%lld\n", i);
    } printf("\n");
}

Main

int main ( ) {
    // freopen("input.txt", "r", stdin);

    int t; scanf("%d", &t);
    REPNE(test, 1, t) {
        LLD a, b;
        scanf("%lld %lld", &a, &b);

        genPrime(a,b);

    }
} 

I can't think of another solution to this problem, the only way I came up is memoization, and it is also handling large integers as well. Help needed.


Solution

  • The approach has a problem that it is generating memoization key, value pairs. Probably they should be tested immediately instead of saving them.

    An easy solution is to iterate over the range m<=x<=n and then check if the number is prime using the optimized prime checker algorithm which takes around (O((n-m)^1/2)), which is quiet less for very large numbers.

    Prime function

    bool ifPrime ( int n ) {
        if ( n==2 ) return true;
        else if ( n%2==0 || n<=1 ) return false;
        for ( int i=3; i<=sqrt(n); i+=2 ) {
            if ( n%i==0 ) return false;
        }
    
        return true;
    }
    

    and you main as

    int main ( ) {
        int t; scanf("%d", &t);
        REPNE(test, 1, t) {
            LLD a, b;
            scanf("%lld %lld", &a, &b);
    
            REPNE(i,a,b) {
                if ( ifPrime(i) ) printf("%lld\n", i);  
            } printf("\n");
        }
    } 
    

    I've tried to code according to your macro definitions, hope it helps :)