How to improve speed for time limit exceeded - c++

Is there any way to improve the running time for this program? I get time limit exceed error from the online judge, and it seems like my program is running slow?
So, this is the question for this program: http://www.spoj.com/problems/PRIME1/
My code (language c):
#include <stdio.h>
void FindPrime (int m, int n)
{
int i, prime = 1;
if (m <= n)
{
for (i = m - 1; i > 1; i--)
{
if (m % i == 0)
{
prime = 0;
break;
}
}
if (prime == 1 && m != 1)
printf ("%d\n", m);
FindPrime (m + 1, n);
}
}
int main ()
{
int num1, num2, i, cases;
scanf ("%d", &cases);
while (cases != 0)
{
scanf ("%d %d", &num1, &num2);
FindPrime (num1, num2);
printf ("\n");
cases--;
}
return 0;
}

To solve this question you need to learn "Sieve of Eratosthenes".
First, get the idea of how it works from here. But, this is not enough to solve this question. Since, the complexity of the algorithm is O(n.log(log(n))). Therefore, if we put n = 1000000000. It will surely fail to execute.
Now, time to optimize it. Read it from here. But, we are done yet.
(Please read this section after you are done with the above two) Since we are to find the prime numbers is the range [m,n]. So, first create a list of prime numbers (let's call it primeList) between the range of 2 to 32000 using sieve of Eratosthenes (sqrt(10^9) = 31622.7, which is less then 32000). Now, check for every number k in the range of [m,n]
3.1. If the number k is in the range of 2-32000, and the number is in primeList. Print it.
3.2. If the number k > 32000, and is not divisible by all the numbers which are <= sqrt(k) and also in primeList. Print it. Else, ignore or don't print it. ( mind it '1' is not prime number).
You may check my solution. But, it is implemented slightly different than i explained although the concept applied is same.

Your code it calculating/listing the prime numbers between to numbers m & n cases number of times. Now you algorithm takes O(n) time for each value of m & hence total time taken by your code for a single case is O(n x m) or O(n^2) times..So in total the time taken is cases * O(n^2).. This is bad..Use some better algorithm to ease the complexity..
Check this modified version of Sieve of Eratosthenes
#include <stdio.h>
#define SIZE (int)(sizeof(boolean) / sizeof(int))
int main(){
int up,low;
int i,j;
printf("\nEnter the upper limit: ");
scanf("%d", &up);
printf("\nEnter the lower limit: ");
scanf("%d", &low);
int boolean[up];
int list[up];
for(i = 0; i < SIZE; i++){
boolean[i] = 1;
list[i] = 2 + i;
}
for(i = 0; i <= up; i++){
if (boolean[i] == 1)
for(j = i +1; j < SIZE; j++)
if(list[j] % list[i] == 0)
boolean[j] = 0;
}
for(i = 0; i < SIZE; i++)
if(boolean[i] == 1 && list[i] >= low && list[i] <= up)
printf("%d ", list[i]);
printf("\n");
return 0;
}
This will not visit one number more than once & hence will reduce the complexity in logarithmic scale.

Related

Minimum Cost to reduce the size of array to 1

Given an array of N numbers (not necessarily sorted). We can merge any two numbers into one and the cost of merging the two numbers is equal to the sum of the two values. The task is to find the total minimum cost of merging all the numbers.
Example:
Let the array A = [1,2,3,4]
Then, we can remove 1 and 2, add both of them and keep the sum back in array. Cost of this step would be (1+2) = 3.
Now, A = [3,3,4], Cost = 3
In second step, we can 3 and 3, add both of them and keep the sum back in array. Cost of this step would be (3+3) = 6.
Now, A = [4,6], Cost = 6
In third step, we can remove both elements from the array and keep the sum back in array again. Cost of this step would be (4+6) = 6.
Now, A = [10], Cost = 10
So, total cost turns out to be 19 (10+6+3).
We will have to pick the 2 smallest elements to minimize our total cost. A simple way to do this is using a min heap structure. We will be able to get the minimum element in O(1) and insertion will be O(log n).
The time complexity of this approach is O(n log n).
But I tried another approach, and wasn't able to find the cases where it fails. The basic idea was that the sum of two smallest elements that we will choose at any time will always be greater than the sum of the pair of elements chosen before. So the "temp" array will always be sorted, and we will be able to access the minimum elements in O(1).
As I am sorting the input array and then simply traversing the array, the complexity of my approach is O(n log n).
int minCost(vector<int>& arr) {
sort(arr.begin(), arr.end());
// temp array will contain the sum of all the pairs of minimum elements
vector<int> temp;
// index for arr
int i = 0;
// index for temp
int j = 0;
int cost = 0;
// while we have more than 1 element combined in both the input and temp array
while(arr.size() - i + temp.size() - j > 1) {
int num1, num2;
// selecting num1 (minimum element)
if(i < arr.size() && j < temp.size()) {
if(arr[i] <= temp[j])
num1 = arr[i++];
else
num1 = temp[j++];
}
else if(i < arr.size())
num1 = arr[i++];
else if(j < temp.size())
num1 = temp[j++];
// selecting num2 (second minimum element)
if(i < arr.size() && j < temp.size()) {
if(arr[i] <= temp[j])
num2 = arr[i++];
else
num2 = temp[j++];
}
else if(i < arr.size())
num2 = arr[i++];
else if(j < temp.size())
num2 = temp[j++];
// appending the sum of the minimum elements in the temp array
int sum = num1 + num2;
temp.push_back(sum);
cost += sum;
}
return cost;
}
Is this approach correct? If not, please let me know what I am missing, and the test cases in which this algorithm fails.
SPOJ Link for the same problem
The logic seems very solid to me... all the computed sums will never be decreasing and therefore you only need to add up either oldest two computed sums, next two elements or oldest sum and next element.
I would just simplify the code:
#include <vector>
#include <algorithm>
#include <stdio.h>
int hsum(std::vector<int> arr) {
int ni = arr.size(), nj = 0, i = 0, j = 0, res = 0;
std::sort(arr.begin(), arr.end());
std::vector<int> temp;
auto get = [&]()->int {
if (j == nj || (i < ni && arr[i] < temp[j])) return arr[i++];
return temp[j++];
};
while ((ni-i)+(nj-j)>1) {
int a = get(), b = get();
res += a+b;
temp.push_back(a + b); nj++;
}
return res;
}
int main() {
fprintf(stderr, "%i\n", hsum(std::vector<int>{1,4,2,3}));
return 0;
}
Very nice idea!
Another improvement is noting that the cumulative length of the two arrays being processed (the original one and the temporary one holding the sums) will decrease at every step.
Since the first step will use two input elements, the fact that the temporary array grows one element at each step will still not be enough for a "walking queue" allocated in the array itself to reach the reading pointer.
This means that there is no need of a temporary array and the space for the sums can be found in the array itself...
int hsum(std::vector<int> arr) {
int ni = arr.size(), nj = 0, i = 0, j = 0, res = 0;
std::sort(arr.begin(), arr.end());
auto get = [&]()->int {
if (j == nj || (i < ni && arr[i] < arr[j])) return arr[i++];
return arr[j++];
};
while ((ni-i)+(nj-j)>1) {
int a = get(), b = get();
res += a+b;
arr[nj++] = a + b;
}
return res;
}
About the error on SPOJ... I tried briefly to search for the problem but I didn't succeed. I tried however generating random arrays of random lengths and checking this solution with what finds a "brute-force" one implemented directly from the specs and I'm reasonably confident that the algorithm is correct.
I know at least one programming arena (Topcoder) where sometimes the problems are carefully crafted so that the computation gives correct results if using unsigned but not if using int (or if using unsigned long long but not if using long long) because of integer overflow.
I don't know if SPOJ also does this kind of nonsense(1)... may be that is the reason some hidden test case fails...
EDIT
Checking with SPOJ the algorithm passes if using long long values... this is the entry I used:
#include <stdio.h>
#include <algorithm>
#include <vector>
int main(int argc, const char *argv[]) {
int n;
scanf("%i", &n);
for (int testcase=0; testcase<n; testcase++) {
int sz; scanf("%i", &sz);
std::vector<long long> arr(sz);
for (int i=0; i<sz; i++) scanf("%lli", &arr[i]);
int ni = arr.size(), nj = 0, i = 0, j = 0;
long long res = 0;
std::sort(arr.begin(), arr.end());
auto get = [&]() -> long long {
if (j == nj || (i < ni && arr[i] < arr[j])) return arr[i++];
return arr[j++];
};
while ((ni-i)+(nj-j)>1) {
long long a = get(), b = get();
res += a+b;
arr[nj++] = a + b;
}
printf("%lli\n", res);
}
return 0;
}
PS: This very kind of computation is also what is needed to build an Huffman tree for entropy coding given the symbols frequency table and thus it's not a mere random exercise but it has practical applications.
(1) I'm saying "nonsense" because in Topcoder they never give problems that require 65 bits; thus it's not a genuine care about overflows, but just setting traps for novices.
Another that I think is a bad practice I saw on TC is that some problems are carefully designed so that the correct algorithm if using C++ will barely fit in the timeout limit: just use another language (and get e.g. a 2× slowdown) and you cannot solve the problem.
First of all, think simple!
When using a priority queue, the problem is easy!
In the first test case :
1 6 3 20
// after pushing to Q
1 3 6 20
// and sum two top items and pop and push!
(1 + 3) 6 20 cost = 4
(4 + 6) 20 cost = 10 + 4
(10 + 20) cost = 30 + 14
30 cost = 44
#include<iostream>
#include<queue>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
priority_queue<long long int, vector<long long int>, greater<long long int>> q;
for (int i = 0; i < n; ++i) {
int k;
cin >> k;
q.push(k);
}
long long int sum = 0;
while (q.size() > 1) {
long long int a = q.top();
q.pop();
long long int b = q.top();
q.pop();
q.push(a + b);
sum += a + b;
}
cout << sum << "\n";
}
}
Basically we need to sort the list in desc order and then find its cost like this.
A.sort(reverse=True)
cost = 0
for i in range(len(A)):
cost += A[i] * (i+1)
return cost

How can I improve my prime number program with Sieve of Eratosthenes algorithm?

My program prints all prime numbers from this expression:
((1 + sin(0.1*i))*k) + 1, i = 1, 2, ..., N.
Input Format:
No more than 100 examples. Every example has 2 positive integers on the same line.
Output Format:
Print each number on a separate line.
Sample Input:
4 10
500 100
Sample Output:
5
17
But my algorithm is not efficient enough. How can I add Sieve of Eratosthenes so it can be efficient enough to not print "Terminated due to timeout".
#include <iostream>
#include <cmath>
using namespace std;
int main() {
long long k, n;
int j;
while (cin >> k >> n) {
if (n>1000 && k>1000000000000000000) continue;
int count = 0;
for (int i = 1; i <= n; i++) {
int res = ((1 + sin(0.1*i)) * k) + 1;
for (j = 2; j < res; j++) {
if (res % j == 0) break;
}
if (j == res) count++;
}
cout << count << endl;
}
system("pause");
You can improve your speed by 10x simply by doing a better job with your trial division. You're testing all integers from 2 to res instead of treating 2 as a special case and testing just odd numbers from 3 to the square root of res:
// k <= 10^3, n <= 10^9
int main() {
unsigned k;
unsigned long long n;
while (cin >> k >> n) {
unsigned count = 0;
for (unsigned long long i = 1; i <= n; i++) {
unsigned long long j, res = (1 + sin(0.1 * i)) * k + 1;
bool is_prime = true;
if (res <= 2 || res % 2 == 0) {
is_prime = (res == 2);
} else {
for (j = 3; j * j <= res; j += 2) {
if (res % j == 0) {
is_prime = false;
break;
}
}
}
if (is_prime) {
count++;
}
}
cout << count << endl;
}
}
Though k = 500 and n = 500000000 is still going to take forty seconds or so.
EDIT: I added a 3rd mean to improve efficiency
EDIT2: Added an explanation why Sieve should not be the solution and some trigonometry relations. Moreover, I added a note on the history of the question
Your problem is not to count all the prime numbers in a given range, but only those which are generated by your function.
Therefore, I don't think that the Sieve of Eratosthenes is the solution for this particular exercise, for the following reason: n is always rather small while k can be very large. If kis very large, then the Sieve algorithm would have to generate a huge number of prime numbers, for finally use it for a small number of candidates.
You can improve the efficiency of you program by three means:
Avoid calculating sin(.) every time. You can use trigonometric relations for example. Moreover, first time you calculate these values, store them in an array and reuse these values. Calculation of sin()is very time consuming
In your test to check if a number is prime, limit the search to sqrt(res). Moreover, consider make the test with odd j only, plus 2
If a candidate res is equal to the previous one, avoid redoing the test
A few trigonometry
If c = cos(0.1) and s = sin(0.1), you can use the relations :
sin (0.1(i+1)) = s*cos (0.1*i) + c*sin(0.1*i))
cos (0.1(i+1)) = c*cos (0.1*i) - s*sin(0.1*i))
If n were large, it should be necessary to recalculate the sin() by the function regularly to avoid too much rounding error calculation. But it should not be the case here as n is always rather small.
However, as I mentioned, it is better to use only the "memorization" trick in a first step and check if it is enough.
A note on the history of this question and why this answer:
Recently, this site received several questions " how to improve my program, to count number of prime numbers generated by this k*sin() function ..." To my knowledge, these questions were all closed as duplicate, under the reason that the Sieve is the solution and was explained in a previous similar (but slightly different) question. Now, the same question reappeared under a slightly different form "How can I insert the Sieve algorithm in this program ... (with k*sin() again)". And then I realised that the Sieve is not the solution. It is not a criticism to previous closes as I made the same mistake in the understanding on the question. However, I think it is time to propose a new solution, even it is does not match the new question perfectly
When you make use of a simple Wheel factorization, you can obtain a very nice speedup of your code. Wheel factorization of order 2 makes use of the fact that all primes bigger than 3 can be written as 6n+1 or 6n+5 for natural n. This means that you only have to do 2 divisions per 6 numbers. Or even further, all primes bigger than 5 can be written as 30n+m, with m in {1,7,11,13,17,19,23,29}. ( 8 divisions per 30 numbers).
Using this simple principle, you can write the following function to test your primes (wheel {2,3}):
bool isPrime(long long num) {
if (num == 1) return false; // 1 is not prime
if (num < 4) return true; // 2 and 3 are prime
if (num % 2 == 0) return false; // divisible by 2
if (num % 3 == 0) return false; // divisible by 3
int w = 5;
while (w*w <= num) {
if(num % w == 0) return false; // not prime
if(num % (w+2) == 0) return false; // not prime
w += 6;
}
return true; // must be prime
}
You can adapt the above for the wheel {2,3,5}. This function can be used in the main program as:
int main() {
long long k, n;
while (cin >> k >> n) {
if (n>1000 && k>1000000000000000000) continue;
int count = 0;
for (int i = 1; i <= n; i++) {
long long res = ((1 + sin(0.1*i)) * k) + 1;
if (isPrime(res)) { count++; }
}
cout << count << endl;
}
return 0;
}
A simple timing gives me for the original code (g++ prime.cpp)
% time echo "6000 100000000" | ./a.out
12999811
echo "6000 100000000" 0.00s user 0.00s system 48% cpu 0.002 total
./a.out 209.66s user 0.00s system 99% cpu 3:29.70 total
while the optimized version gives me
% time echo "6000 100000000" | ./a.out
12999811
echo "6000 100000000" 0.00s user 0.00s system 51% cpu 0.002 total
./a.out 10.12s user 0.00s system 99% cpu 10.124 total
Other improvements can be made but might have minor effects:
precompute your sine-table sin(0.1*i) for i from 0 to 1000. This will avoid recomputing those sines over and over. This however, has a minor impact as most time is wasted on the primetest.
Checking if res(i) == res(i+1): this has barely any impact as, depending on n and k most consecutive res are not equal.
Use a lookup table, might be handier, this does have an impact.
original answer:
My suggestion is the following:
Precompute your sinetable sin(0.1*i) for i from 0 to 1000. This will avoid recomputing those sines over and over. Also, do it smart (see point 3)
Find the largest possible value of res which is res_max=(2*k)+1
Find all primes for res_max using the Sieve of Eratosthenes. Also, realize that all primes bigger than 3 can be written as 6n+1 or 6n+5 for natural n. Or even further, all primes bigger than 5 can be written as 30n+m, with m in {1,7,11,13,17,19,23,29}. This is what is called Wheel factorization. So do not bother checking any other number. (a tiny bit more info here)
Have a lookup table that states if a number is a prime.
Do all your looping over the lookup table.

Improving optimization of nested loop

I'm making a simple program to calculate the number of pairs in an array that are divisible by 3 array length and values are user determined.
Now my code is perfectly fine. However, I just want to check if there is a faster way to calculate it which results in less compiling time?
As the length of the array is 10^4 or less compiler takes less than 100ms. However, as it gets more to 10^5 it spikes up to 1000ms so why is this? and how to improve speed?
#include <iostream>
using namespace std;
int main()
{
int N, i, b;
b = 0;
cin >> N;
unsigned int j = 0;
std::vector<unsigned int> a(N);
for (j = 0; j < N; j++) {
cin >> a[j];
if (j == 0) {
}
else {
for (i = j - 1; i >= 0; i = i - 1) {
if ((a[j] + a[i]) % 3 == 0) {
b++;
}
}
}
}
cout << b;
return 0;
}
Your algorithm has O(N^2) complexity. There is a faster way.
(a[i] + a[j]) % 3 == ((a[i] % 3) + (a[j] % 3)) % 3
Thus, you need not know the exact numbers, you need to know their remainders of division by three only. Zero remainder of the sum can be received with two numbers with zero remainders (0 + 0) and with two numbers with remainders 1 and 2 (1 + 2).
The result will be equal to r[1]*r[2] + r[0]*(r[0]-1)/2 where r[i] is the quantity of numbers with remainder equal to i.
int r[3] = {};
for (int i : a) {
r[i % 3]++;
}
std::cout << r[1]*r[2] + (r[0]*(r[0]-1)) / 2;
The complexity of this algorithm is O(N).
I've encountered this problem before, and while I don't find my particular solution, you could improve running times by hashing.
The code would look something like this:
// A C++ program to check if arr[0..n-1] can be divided
// in pairs such that every pair is divisible by k.
#include <bits/stdc++.h>
using namespace std;
// Returns true if arr[0..n-1] can be divided into pairs
// with sum divisible by k.
bool canPairs(int arr[], int n, int k)
{
// An odd length array cannot be divided into pairs
if (n & 1)
return false;
// Create a frequency array to count occurrences
// of all remainders when divided by k.
map<int, int> freq;
// Count occurrences of all remainders
for (int i = 0; i < n; i++)
freq[arr[i] % k]++;
// Traverse input array and use freq[] to decide
// if given array can be divided in pairs
for (int i = 0; i < n; i++)
{
// Remainder of current element
int rem = arr[i] % k;
// If remainder with current element divides
// k into two halves.
if (2*rem == k)
{
// Then there must be even occurrences of
// such remainder
if (freq[rem] % 2 != 0)
return false;
}
// If remainder is 0, then there must be two
// elements with 0 remainder
else if (rem == 0)
{
if (freq[rem] & 1)
return false;
}
// Else number of occurrences of remainder
// must be equal to number of occurrences of
// k - remainder
else if (freq[rem] != freq[k - rem])
return false;
}
return true;
}
/* Driver program to test above function */
int main()
{
int arr[] = {92, 75, 65, 48, 45, 35};
int k = 10;
int n = sizeof(arr)/sizeof(arr[0]);
canPairs(arr, n, k)? cout << "True": cout << "False";
return 0;
}
That works for a k (in your case 3)
But then again, this is not my code, but the code you can find in the following link. with a proper explanation. I didn't just paste the link since it's bad practice I think.

What variation of Sieve of Eratosthenes is this?

I am trying to solve a problem Prime Path on spoj, and I am trying to understand the solution I found on github. The broad logic to solve this problem is to generate all four digit primes and add an edge iff we can go from one prime to the next by changing a single digit. This solution I found uses sieve to generate all primes. The sieve of eratosthenes on wiki is different compared to the sieve function in this solution. Just need help on understanding the variation of sieve function in the following code:
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <cstring>
using namespace std;
#define MAX 10000
#define LMT 100
bool flag[MAX], visited[MAX];
int d[MAX];
void sieve()
{
register int i, j, k;
flag[0] = flag[1] = 1;
for(i=1000; i<MAX; i+=2)
flag[i] = 1;
for(i=3; i<LMT; i+=2)
if(!flag[i])
for(j=i*i, k=i<<1; j<MAX; j+=k)
flag[j] = 1;
}
int bfs(int start, int end)
{
queue< int > Q;
int i, u, v, t, j;
char temp[10], x;
Q.push(start);
memset(visited, 0, sizeof visited);
memset(d, -1, sizeof d);
d[start] = 0;
visited[start] = 1;
while(!Q.empty())
{
u = Q.front();
Q.pop();
sprintf(temp,"%d",u);
x = temp[0];
for(t=0;t<4;t++)
{
if(t==0 || t==3)
i=1;
else
i=0;
if(t==3)
j=2;
else
j=1;
x = temp[t];
for(;i<=9;i+=j)
{
temp[t] = i+'0';
v = atoi(temp);
if(v!=u && !visited[v] && !flag[v])
{
Q.push(v);
visited[v] = 1;
d[v] = d[u]+1;
if(v==end)
return d[end];
}
}
temp[t] = x;
}
}
return d[end];
}
int main()
{
int a, b, t, dist;
sieve();
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &a, &b);
if(a==b)
{
printf("0\n");
continue;
}
dist = bfs(a,b);
if(dist==-1)
printf("impossible\n");
else
printf("%d\n", dist);
}
return 0;
}
What is the sieve function computing here? I am unable to understand why the author has listed only the odd numbers to calculate the primes, and why the loops run upto LMT, i.e 100? Appreciate your help.
I am unable to understand why the author has listed only the odd numbers to calculate the primes
Because the only even prime is 2, the rest are all odd. So you only need to check odd numbers.
and why the loops run upto LMT, i.e 100?
Because 100 * 100 = 10000, so you can sieve all 4 digit primes by doing the sieve up to 100. By marking off multiples of numbers <= 100, you will also take care of numbers x > 100 that are non-prime and therefore must have divisors below sqrt(x).
for(j=i*i, k=i<<1; j<MAX; j+=k)
flag[j] = 1;
Note that i << 1 is just 2*i. Why 2*i? Remember that we only care about the odd numbers. i*i + i = i*(i+1), which will be even, and so on, you will land on even numbers sometimes if you use + i. So the code uses + 2i to avoid landing on even numbers.
Also, we start from i*i because the previous numbers will have been been sieved by previous iterations of i, for the same reason: if a j < i*i was not prime, it must have had a factor at most sqrt(j), which would have been addressed previously.
You can optimize the code even more if you want, as exercises:
You only sieve the odd numbers, but you still alocate memory for the evens. Implement the sieve with half the memory;
You only need 1 bit for each number. Implement the sieve with 16 times less memory (8 times less for not using a bool for each number and 2 times less for not allocating memory for the even numbers).

Print first 1 million primes in 1 sec with constraints program size 50000 bytes and limited Memory

I tried sieve of Eratosthenes: Following is my code:
void prime_eratos(int N) {
int root = (int)sqrt((double)N);
bool *A = new bool[N + 1];
memset(A, 0, sizeof(bool) * (N + 1));
for (int m = 2; m <= root; m++) {
if (!A[m]) {
printf("%d ",m);
for (int k = m * m; k <= N; k += m)
A[k] = true;
}
}
for (int m = root; m <= N; m++)
if (!A[m])
printf("%d ",m);
delete [] A;
}
int main(){
prime_eratos(179426549);
return 0;
}
It took time : real 7.340s in my system.
I also tried Sieve of Atkins(studied somewhere faster than
sieve of Eratosthenes).
But in my case,it took time : real 10.433s .
Here is the code:
int main(){
int limit=179426549;
int x,y,i,n,k,m;
bool *is_prime = new bool[179426550];
memset(is_prime, 0, sizeof(bool) * 179426550);
/*for(i=5;i<=limit;i++){
is_prime[i]=false;
}*/
int N=sqrt(limit);
for(x=1;x<=N;x++){
for(y=1;y<=N;y++){
n=(4*x*x) + (y*y);
if((n<=limit) &&(n%12 == 1 || n%12==5))
is_prime[n]^=true;
n=(3*x*x) + (y*y);
if((n<=limit) && (n%12 == 7))
is_prime[n]^=true;
n=(3*x*x) - (y*y);
if((x>y) && (n<=limit) && (n%12 == 11))
is_prime[n]^=true;
}
}
for(n=5;n<=N;n++){
if(is_prime[n]){
m=n*n;
for(k=m;k<=limit;k+=m)
is_prime[k]=false;
}
}
printf("2 3 ");
for(n=5;n<=limit;n++){
if(is_prime[n])
printf("%d ",n);
}
delete []is_prime;
return 0;
}
Now,I wonder,none is able to output 1 million primes in 1 sec.
One approach could be:
I store the values in Array but the program size is limited.
Could someone suggest me some way to get first 1 million primes in less
than a sec satisfying the constraints(discussed above) ?
Thanx !!
Try
int main()
{
std::ifstream primes("Filecontaining1MillionPrimes.txt");
std::cout << primes.rdbuf();
}
You've counted the primes incorrectly. The millionth prime is 15485863, which is a lot smaller than you suggest.
You can speed your program and save space by eliminating even numbers from your sieve.
The fastest way I know to check if a number is prime is to check for compositeness, I've implemented the http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test with great sucess for RSA, it is probabilistic, with high degree of success depending on how many times you run it.
Step 1. don't do a printf
Step 2. buy a faster computer.