Codebank: Finding nth prime

Mar 18, 2013 at 12:09am
Not the fastest but an elegant code written by me.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// This code was written by Mert Ener
#include <time.h>
#include <iostream>

// Requires a run button on Windows form.
private: System::Void button1_Click_1(System::Object^  sender, System::EventArgs^  e) {

UInt64 cloc = clock();
long o, m = 1;
long k = long::Parse(textBox1->Text)-2; // The textbox you entered for the nth prime.
vector<int> p(1,2);
for( long n = 0; n <= k; n++ ) {
m += 2;
for( long l = 1;o=p[l],o*o<=m; l++ ) {
if (m % p[l] == 0) {
m += 2;
l=0;}}
p.push_back(m);}
textBox2->Text = p[k+1].ToString(); // The textbox for the result.
MessageBox::Show("It took me " + (clock() - cloc).ToString() + " milliseconds to find your prime.");}
Last edited on Mar 20, 2013 at 10:44am
Mar 18, 2013 at 12:17am
Got an error on line 6 when I compile. This looks a bit like Java
Mar 18, 2013 at 12:22am
This looks a bit like Java

Looks like C++\CLI - Microsoft's managed version of C++.

Although I don't think line 6 would compile anyway.
Last edited on Mar 18, 2013 at 12:25am
Mar 18, 2013 at 2:33am
Oh sorry, my bad. That's right
Looks like C++\CLI - Microsoft's managed version of C++.

It is a code written with VS2012 in C++.Net. It is for a windows userform with two textboxes and line 6 represents a click to run button.
The core of the code is here
1
2
3
4
5
6
7
8
9
10
11
long o,m = 1;
long k = "nth prime you like";
vector<int> p(1,2);
for( long n = 0; n <= k; n++ ) {
m += 2;
for( long l = 1;o=p[l],o*o<=m; l++ ) {
if (m % p[l] == 0) {
m += 2;
l=0;}}
p.push_back(m);}
"The result is" = p[k+1]

and you may modify it as you like.
Last edited on Mar 20, 2013 at 10:46am
Mar 20, 2013 at 3:26am
Mar 20, 2013 at 11:05am
Yeah, your code also looks cool! In the forums, it has been said 4 sec. is a optimistic result for 1000000th prime. My code finds in less than 2 seconds on an ordinary pc.
Last edited on Mar 20, 2013 at 11:15am
Mar 21, 2013 at 1:04am
I get floating point exception when I run yours
Mar 21, 2013 at 11:12am
Yeah, can be. No problem. The code changed a bit also. I'll update in a free time.
Mar 21, 2013 at 8:52pm
Finally, it is a shortened and stable version of my original code.

1
2
3
4
5
6
7
8
int k = "the nth prime you like" -1;
int l,m=1,n,o;
int*p;p=new int [k+1],p[0]=2;

for(n=1;m+=2,n<=k;p[n]=m,n+=1)
for(l=1,o=3;o*o<=m;(m%o==0)?(m+=2,l=1,o=3):(l+=1,o=p[l]));

"the result" = p[k]


In fact the exact expression of my original code is this below. Even it is a shorter and slightly faster way,
1
2
3
4
5
6
7
8
int k = "the nth prime you like" -1;
int l,m=1,n,o;
int*p;p=new int [k+1],p[0]=2;

for(n=1;m+=2,n<=k;p[n]=m,n++)
for(l=1;o=p[l],o*o<=m;(m%o==0)?(m+=2,l=1):(l++));

"the result" = p[k]

however it is unstable because of memory initialization issues and I couldn't overcome it. After 1000000th query it is giving division-by-zero error. Sometimes o gets 0 value even there is nothing such as 0 in array p. I can prove it because it runs so well around 1000000th queries. And m%0 causes the error. That's why I had to secure o many times in the first code. If someone can handle it, will be my welcome.
But the first code runs perfectly for 10000000th query around 40 seconds on an ordinary pc.
Last edited on Mar 21, 2013 at 9:26pm
Mar 21, 2013 at 10:05pm
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
#include <iostream>
#include <cmath>
#include <cassert>
#include <limits>
#include <cstdint>
#include <vector>

int main()
{
   constexpr std::size_t n = 10000000 ;

   // use the prime number theorem to get an upper bound on the nth prime
   const auto logn = std::log(n) ;
   const std::size_t SZ = n * ( logn + std::log(logn) ) + 1 ;
   assert( SZ < std::numeric_limits<std::size_t>::max() ) ;

   // generate a prime number sieve upto the upper_bound
   std::vector<bool> sieve( SZ, true ) ;
   const std::size_t RP1 = std::sqrt(SZ) + 2 ;
   for( std::size_t i = 2 ; i < RP1 ; ++i ) if( sieve[i] )
       for( std::size_t j = i+i ; j < SZ ; j += i ) sieve[j] = false ;

   // and count till the nth prime number
   std::size_t cnt = 0 ;
   for( std::size_t i = 2 ; i < SZ ; ++i ) if( sieve[i] )
   {
      ++cnt ;
      if( cnt == n )
      {
         std::cout << "the " << n << "th prime number is " << i << '\n' ;
         break ;
      }
   }
}


http://liveworkspace.org/code/1Ti4nB$1
Mar 21, 2013 at 10:12pm

1
2
  constexpr std::size_t n = 10000000 ;
   

constexpr: unidentified,
size_t: cannot be defined in current scope,
n: expected (;)
errors.
Last edited on Mar 21, 2013 at 10:12pm
Mar 21, 2013 at 10:18pm
You need a compiler that supports C++11, the latest standard of C++ that was released in 2011.


Branflakes91093 wrote:
Looks like C++\CLI - Microsoft's managed version of C++.
Just like with Windows, they actually use a forward slash and not a backslash.
Mar 22, 2013 at 6:15am
Mar 22, 2013 at 4:58pm
Wowww, It is amazing! I didn't know about that "Sieve of Eratosthenes" therorem. It works around10 times faster than my code! Amsome ;) It has some logarithmic expressions. I'll inspect this.
Last edited on Mar 22, 2013 at 5:00pm
Mar 22, 2013 at 5:15pm
> I didn't know about that "Sieve of Eratosthenes" therorem.

The theorem is called the "prime number theorem"
http://en.wikipedia.org/wiki/Prime_number_theorem

The algorithm used for generating prime numbers is the "sieve of Eratosthenes"; the oldest and also the simplest sieve algorithm.
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
Topic archived. No new replies allowed.