Is there a simple algorithm that can determine if X is prime?

后端 未结 16 1489
离开以前
离开以前 2020-12-01 00:32

I have been trying to work my way through Project Euler, and have noticed a handful of problems ask for you to determine a prime number as part of it.

  1. I kno

相关标签:
16条回答
  • 2020-12-01 00:42

    The first algorithm is quite good and used a lot on Project Euler. If you know the maximum number that you want you can also research Eratosthenes's sieve.

    If you maintain the list of primes you can also refine the first algo to divide only with primes until the square root of the number.

    With these two algoritms (dividing and the sieve) you should be able to solve the problems.

    Edit: fixed name as noted in comments

    0 讨论(0)
  • 2020-12-01 00:42

    Maybe this implementation in Java can be helpful:

    public class SieveOfEratosthenes {
    
        /**
         * Calling this method with argument 7 will return: true true false false true false true false
         * which must be interpreted as : 0 is NOT prime, 1 is NOT prime, 2 IS prime, 3 IS prime, 4 is NOT prime
         * 5 is prime, 6 is NOT prime, 7 is prime.
         * Caller may either revert the array for easier reading, count the number of primes or extract the prime values
         * by looping.
         * @param upTo Find prime numbers up to this value. Must be a positive integer.
         * @return a boolean array where index represents the integer value and value at index returns
         * if the number is NOT prime or not.
         */
        public static boolean[] isIndexNotPrime(int upTo) {
            if (upTo < 2) {
                return new boolean[0];
            }
    
            // 0-index array, upper limit must be upTo + 1
            final boolean[] isIndexNotPrime = new boolean[upTo + 1];
    
            isIndexNotPrime[0] = true; // 0 is not a prime number.
            isIndexNotPrime[1] = true; // 1 is not a prime number.
    
            // Find all non primes starting from 2 by finding 2 * 2, 2 * 3, 2 * 4 until 2 * multiplier > isIndexNotPrime.len
            // Find next by 3 * 3 (since 2 * 3 was found before), 3 * 4, 3 * 5 until 3 * multiplier > isIndexNotPrime.len
            // Move to 4, since isIndexNotPrime[4] is already True (not prime) no need to loop..
            // Move to 5, 5 * 5, (2 * 5 and 3 * 5 was already set to True..) until 5 * multiplier > isIndexNotPrime.len
            // Repeat process until i * i > isIndexNotPrime.len.
            // Assume we are looking up to 100. Break once you reach 11 since 11 * 11 == 121 and we are not interested in
            // primes above 121..
            for (int i = 2; i < isIndexNotPrime.length; i++) {
                if (i * i >= isIndexNotPrime.length) {
                    break;
                }
                if (isIndexNotPrime[i]) {
                    continue;
                }
                int multiplier = i;
                while (i * multiplier < isIndexNotPrime.length) {
                    isIndexNotPrime[i * multiplier] = true;
                    multiplier++;
                }
            }
    
            return isIndexNotPrime;
        }
    
        public static void main(String[] args) {
            final boolean[] indexNotPrime = SieveOfEratosthenes.isIndexNotPrime(7);
            assert !indexNotPrime[2]; // Not (not prime)
            assert !indexNotPrime[3]; // Not (not prime)
            assert indexNotPrime[4]; // (not prime)
            assert !indexNotPrime[5]; // Not (not prime)
            assert indexNotPrime[6]; // (not prime)
            assert !indexNotPrime[7]; // Not (not prime)
        }
    }
    
    0 讨论(0)
  • 2020-12-01 00:43

    Here is a simple primality test in D (Digital Mars):

    /** 
     * to compile:
     * $ dmd -run prime_trial.d
     * to optimize:
     * $ dmd -O -inline -release prime_trial.d 
     */
    module prime_trial;
    
    import std.conv : to;  
    import std.stdio : w = writeln;
    
    /// Adapted from: http://www.devx.com/vb2themax/Tip/19051 
    bool 
    isprime(Integer)(in Integer number) 
    {
      /* manually test 1, 2, 3 and multiples of 2 and 3 */
      if (number == 2 || number == 3)
        return true;
      else if (number < 2 || number % 2 == 0 || number % 3 == 0)
        return false;
    
      /* we can now avoid to consider multiples 
       * of 2 and 3. This can be done really simply 
       * by starting at 5 and incrementing by 2 and 4 
       * alternatively, that is: 
       *    5, 7, 11, 13, 17, 19, 23, 25, 29, 31, 35, 37, ...    
       * we don't need to go higher than the square root of the number */
      for (Integer divisor = 5, increment = 2; divisor*divisor <= number; 
           divisor += increment, increment = 6 - increment) 
        if (number % divisor == 0)
          return false;
    
      return true;  // if we get here, the number is prime
    }
    
    /// print all prime numbers less then a given limit
    void main(char[][] args) 
    {
      const limit = (args.length == 2) ? to!(uint)(args[1]) : 100;
      for (uint i = 0; i < limit; ++i) 
        if (isprime(i))
          w(i);
    }
    
    0 讨论(0)
  • 2020-12-01 00:43

    Is not optimized but it's a very simple function.

        function isprime(number){
    
        if (number == 1)
            return false;
    
        var times = 0;
    
        for (var i = 1; i <= number; i++){
            if(number % i == 0){
                times ++;
            }
        }
            if (times > 2){
                return false;
            }
    
        return true;
        }
    
    0 讨论(0)
  • 2020-12-01 00:44

    I see that Fermat's primality test has already been suggested, but I've been working through Structure and Interpretation of Computer Programs, and they also give the Miller-Rabin test (see Section 1.2.6, problem 1.28) as another alternative. I've been using it with success for the Euler problems.

    0 讨论(0)
  • 2020-12-01 00:51

    To generate all prime numbers less than a limit Sieve of Eratosthenes (the page contains variants in 20 programming languages) is the oldest and the simplest solution.

    In Python:

    def iprimes_upto(limit):
        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
    

    Example:

    >>> list(iprimes_upto(15))
    [2, 3, 5, 7, 11, 13]
    
    0 讨论(0)
提交回复
热议问题