Prime number calculation fun

前端 未结 18 1752
深忆病人
深忆病人 2020-12-05 15:32

We\'re having a bit of fun here at work. It all started with one of the guys setting up a Hackintosh and we were wondering whether it was faster than a Windows Box of (nearl

相关标签:
18条回答
  • 2020-12-05 15:37

    It takes us under a second (2.4GHz) to generate the first 150000 prime numbers in Python using Sieve of Eratosthenes:

    #!/usr/bin/env python
    def iprimes_upto(limit):
        """Generate all prime numbers less then limit.
    
        http://stackoverflow.com/questions/188425/project-euler-problem#193605
        """
        is_prime = [True] * limit
        for n in range(2, limit):
            if is_prime[n]:
               yield n
               for i in range(n*n, limit, n): # start at ``n`` squared
                   is_prime[i] = False
    
    def sup_prime(n):
        """Return an integer upper bound for p(n).
    
           p(n) < n (log n + log log n - 1 + 1.8 log log n / log n)
    
           where p(n) is the n-th prime. 
           http://primes.utm.edu/howmany.shtml#2
        """
        from math import ceil, log
        assert n >= 13
        pn = n * (log(n) + log(log(n)) - 1 + 1.8 * log(log(n)) / log(n))
        return int(ceil(pn))
    
    if __name__ == '__main__':
        import sys
        max_number_of_primes = int(sys.argv[1]) if len(sys.argv) == 2 else 150000
        primes = list(iprimes_upto(sup_prime(max_number_of_primes)))
        print("Generated %d primes" % len(primes))
        n = 100
        print("The first %d primes are %s" % (n, primes[:n]))
    

    Example:

    $ python primes.py
    
    Generated 153465 primes
    The first 100 primes are [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 
    43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 
    127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197,
    199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
    283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379,
    383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
    467, 479, 487, 491, 499, 503, 509, 521, 523, 541]
    
    0 讨论(0)
  • 2020-12-05 15:37

    You should be able to make the inner loop twice as fast by only evaluating the odd numbers. Not sure if this is valid Java, I'm used to C++, but I'm sure it can be adapted.

                if (current != 2 && current % 2 == 0)
                        prime = false;
                else {
                        for (int i = 3; i < top; i+=2) {
                                if (current % i == 0) {
                                        prime = false;
                                        break;
                                }
                        }
                }
    
    0 讨论(0)
  • 2020-12-05 15:38

    In C#:

    class Program
    {
        static void Main(string[] args)
        {
            int count = 0;
            int max = 150000;
            int i = 2;
    
            DateTime start = DateTime.Now;
            while (count < max)
            {
                if (IsPrime(i))
                {
                    count++;
                }
    
                i++;
    
            }
            DateTime end = DateTime.Now;
    
            Console.WriteLine("Total time taken: " + (end - start).TotalSeconds.ToString() + " seconds");
            Console.ReadLine();
        }
    
        static bool IsPrime(int n)
        {
            if (n < 4)
                return true;
            if (n % 2 == 0)
                return false;
    
            int s = (int)Math.Sqrt(n);
            for (int i = 2; i <= s; i++)
                if (n % i == 0)
                    return false;
    
            return true;
        }
    }
    

    Output:

    Total time taken: 2.087 seconds

    0 讨论(0)
  • 2020-12-05 15:39

    Here is a fast and simple solution:

    • Finding primes less than 100000; 9592 were found in 5 ms
    • Finding primes less than 1000000; 78498 were found in 20 ms
    • Finding primes less than 10000000; 664579 were found in 143 ms
    • Finding primes less than 100000000; 5761455 were found in 2024 ms
    • Finding primes less than 1000000000; 50847534 were found in 23839 ms

      //returns number of primes less than n
      private static int getNumberOfPrimes(final int n)
      {
          if(n < 2) 
              return 0;
          BitSet candidates = new BitSet(n - 1);
          candidates.set(0, false);
          candidates.set(1, false);
          candidates.set(2, n);
          for(int i = 2; i < n; i++)
              if(candidates.get(i))
                  for(int j = i + i; j < n; j += i)
                      if(candidates.get(j) && j % i == 0)
                          candidates.set(j, false);            
          return candidates.cardinality();
      }    
      
    0 讨论(0)
  • 2020-12-05 15:39

    I bet Miller-Rabin would be faster. If you test enough contiguous numbers it becomes deterministic, but I wouldn't even bother. Once a randomized algorithm reaches the point that its failure rate is equal to the likelihood that a CPU hiccup will cause a wrong result, it just doesn't matter any more.

    0 讨论(0)
  • 2020-12-05 15:41

    Does the re-declaration of the variable prime

            while (count < topPrime) {
    
                boolean prime = true;
    

    within the loop make it inefficient? (I assume it doesn't matter, since I would think Java would optimize this)

    boolean prime;        
    while (count < topPrime) {
    
                prime = true;
    
    0 讨论(0)
提交回复
热议问题