I wrote this code to show the primes between 1 and 100. The only condition is to do not use functions, whole code should be inline. I would ask if I can improve (optimize) it mu
Depends which optimisation you're looking to do. Yours is as good as possible that I can see if you're optimising for space first, time second (well, close - as long as you listen to @Paul, it will be). If you reverse the priorities, the Sieve of Erastothenes is faster (but will take up 100 booleans of your memory).
Two simple optimizations you could do:
cout << 2 << '\t';
for (int i = 3; i <= 100; ++i) {
for (int j = 3, l = (int)sqrt(i); j <= l; j += 2) {
if (i % j == 0) {
cout << i << '\t';
break;
}
}
What I did:
Math:
j > sqrt(i)
, there's no need to go further than that. Note however that sqrt
is an expensive function; for your small sample (from 1 to 100), it might (read, will surely) cost you more to use it.j += 2
instead of incrementing j
one by one Micro-optimizations:
++i
instead of i++
; the latter has a temporary variable in which it stores the original value of i
; the former does not.'\t'
as a character not as a string "\t"
.(These micro-optimizations are probably made automatically by the compiler anyway, but there's no harm in knowing about them.)
The most efficient way to accomplish this is the Sieve of Eratosthenes. Here's an incremental version, specifically tailored to producing the primes up to 100, one by one (maximum up to 120, because 121 == 11 * 11).
int m3 = 9, m5 = 25, m7 = 49, i = 3;
printf("2 ");
for( ; i < 100; i += 2 )
{
if( i != m3 && i != m5 && i != m7)
printf("%d ", i);
else
{
if( i == m3 ) m3 += 6;
if( i == m5 ) m5 += 10;
if( i == m7 ) m7 += 14;
}
}
You are checking every number from 2 to 100. But since 2 is the only even prime number, you can skip every even number after 2. This goes for both i
and j
. So start i
and j
at 3, and increment them by 2.
#include<iostream>
using namespace std;
int main() {
cout<<"Prime numbers between 1 and 100 are:"<<endl;
cout<<"2"<<"\t";
for (int i=3; i<100;i+=2) {
// This loop stops either when j*j>i or when i is divisible by j.
// The first condition means prime, the second, not prime.
int j=3;
for(;j*j<=i && i%j!=0; j+=2); // No loop body
if (j*j>i) cout << i << "\t";
}
cout<<endl;
return 0;
}
In addition to the trick mentioned above, I've added the condition j*j<=i
which logically is the exact same as j<=sqrt(i)
. There's no need to compute the square root when you can do a simple multiplication.
for(int j=2;j<i;j++){
This one is not nice.
First of all, you only need to check for j <= sqrt(i)
, as for example 7 will never divide 12 without a rest.
Second, you should keep track of all previously found prime numbers; keep it in vector and only do this loop for it's contents and for that condition I wrote.
You could optimise your existing code:
You could use a different method:
On the Sieve of Erastoses just removing the numbers divisable by 2,3 and 5 would significantly reduce the number of times you need to test for primality.