Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Many thanks to all who gave helpful answers. Here are my implementations of a few different methods of finding the first <em>n</em> primes in C#. The first two methods are pretty much what was posted here. (The posters names are next to the title.) I plan on doing the sieve of Atkin sometime, although I suspect it won't be quite as simple as the methods here currently. If anybody can see any way of improving any of these methods I'd love to know :-)</p> <p><strong>Standard Method</strong> (<a href="https://stackoverflow.com/questions/1042902/most-elegant-way-to-generate-prime-numbers/1043007#1043007">Peter Smit</a>, <a href="https://stackoverflow.com/questions/1042902/most-elegant-way-to-generate-prime-numbers/1043002#1043002">jmservera</a>, <a href="https://stackoverflow.com/questions/1042902/most-elegant-way-to-generate-prime-numbers/1042969#1042969">Rekreativc</a>)</p> <p>The first prime number is 2. Add this to a list of primes. The next prime is the next number that is not evenly divisible by any number on this list.</p> <pre><code>public static List&lt;int&gt; GeneratePrimesNaive(int n) { List&lt;int&gt; primes = new List&lt;int&gt;(); primes.Add(2); int nextPrime = 3; while (primes.Count &lt; n) { int sqrt = (int)Math.Sqrt(nextPrime); bool isPrime = true; for (int i = 0; (int)primes[i] &lt;= sqrt; i++) { if (nextPrime % primes[i] == 0) { isPrime = false; break; } } if (isPrime) { primes.Add(nextPrime); } nextPrime += 2; } return primes; } </code></pre> <p>This has been optimised by only testing for divisibility up to the square root of the number being tested; and by only testing odd numbers. This can be further optimised by testing only numbers of the form <code>6k+[1, 5]</code>, or <code>30k+[1, 7, 11, 13, 17, 19, 23, 29]</code> or <a href="http://en.wikipedia.org/wiki/Prime_number#Examples_and_first_properties" rel="nofollow noreferrer">so on</a>.</p> <p><strong>Sieve of Eratosthenes</strong> (<a href="https://stackoverflow.com/questions/1042902/most-elegant-way-to-generate-prime-numbers/1043247#1043247">starblue</a>)</p> <p><a href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes" rel="nofollow noreferrer">This finds all the primes to <em>k</em></a>. To make a list of the first <em>n</em> primes, we first need to approximate value of the <em>n</em>th prime. The following method, <a href="https://stackoverflow.com/questions/1042717/is-there-a-way-to-find-the-approximate-value-of-the-nth-prime/1069023#1069023">as described here</a>, does this.</p> <pre><code>public static int ApproximateNthPrime(int nn) { double n = (double)nn; double p; if (nn &gt;= 7022) { p = n * Math.Log(n) + n * (Math.Log(Math.Log(n)) - 0.9385); } else if (nn &gt;= 6) { p = n * Math.Log(n) + n * Math.Log(Math.Log(n)); } else if (nn &gt; 0) { p = new int[] { 2, 3, 5, 7, 11 }[nn - 1]; } else { p = 0; } return (int)p; } // Find all primes up to and including the limit public static BitArray SieveOfEratosthenes(int limit) { BitArray bits = new BitArray(limit + 1, true); bits[0] = false; bits[1] = false; for (int i = 0; i * i &lt;= limit; i++) { if (bits[i]) { for (int j = i * i; j &lt;= limit; j += i) { bits[j] = false; } } } return bits; } public static List&lt;int&gt; GeneratePrimesSieveOfEratosthenes(int n) { int limit = ApproximateNthPrime(n); BitArray bits = SieveOfEratosthenes(limit); List&lt;int&gt; primes = new List&lt;int&gt;(); for (int i = 0, found = 0; i &lt; limit &amp;&amp; found &lt; n; i++) { if (bits[i]) { primes.Add(i); found++; } } return primes; } </code></pre> <p><strong>Sieve of Sundaram</strong></p> <p>I only discovered <a href="http://en.wikipedia.org/wiki/Sieve_of_Sundaram" rel="nofollow noreferrer">this sieve</a> recently, but it can be implemented quite simply. My implementation isn't as fast as the sieve of Eratosthenes, but it is significantly faster than the naive method.</p> <pre><code>public static BitArray SieveOfSundaram(int limit) { limit /= 2; BitArray bits = new BitArray(limit + 1, true); for (int i = 1; 3 * i + 1 &lt; limit; i++) { for (int j = 1; i + j + 2 * i * j &lt;= limit; j++) { bits[i + j + 2 * i * j] = false; } } return bits; } public static List&lt;int&gt; GeneratePrimesSieveOfSundaram(int n) { int limit = ApproximateNthPrime(n); BitArray bits = SieveOfSundaram(limit); List&lt;int&gt; primes = new List&lt;int&gt;(); primes.Add(2); for (int i = 1, found = 1; 2 * i + 1 &lt;= limit &amp;&amp; found &lt; n; i++) { if (bits[i]) { primes.Add(2 * i + 1); found++; } } return primes; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload