Advertisement
ClickerMonkey

Prime Numbers

May 23rd, 2013
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.97 KB | None | 0 0
  1. package prime;
  2.  
  3. import java.io.PrintStream;
  4. import java.util.ArrayList;
  5. import java.util.Arrays;
  6. import java.util.Collection;
  7.  
  8. /**
  9.  * A prime number utility for generating X number of primes, determining whether
  10.  * a given number is prime, and computing the prime factorization for a number.
  11.  *
  12.  * For determining whether a number N is prime, you only need to know all the
  13.  * primes up to and including sqrt(N).
  14.  *
  15.  * @author Philip Diffenderfer
  16.  *
  17.  */
  18. public class Prime
  19. {
  20.  
  21.     public static void main( String[] args )
  22.     {
  23.         Prime p = new Prime( 10000000 );
  24.  
  25.         // Load 100,000 primes into cache
  26.         long t0 = System.nanoTime();
  27.         p.initialize( 10000000 );
  28.        
  29.         System.out.println( ( System.nanoTime() - t0 ) * 0.000000001 + " seconds to initialize " + (p.length + 1) + " primes" );
  30.  
  31.         // Last Prime
  32.         System.out.println( p.primes[p.length] );
  33.  
  34.         // Prime Factors
  35.         System.out.println( p.factorize( 83475L, new ArrayList<Long>() ) );
  36.     }
  37.  
  38.     // The cache of prime numbers
  39.     private long[] primes;
  40.  
  41.     // The index of the last prime number in the cache
  42.     private int length;
  43.  
  44.     /**
  45.      * Instantiates a new Prime class with a maximum number of primes it can
  46.      * generate.
  47.      *
  48.      * @param primeCountMax
  49.      *            The maximum number of primes this class may be able to store.
  50.      */
  51.     public Prime( int primeCountMax )
  52.     {
  53.         primes = new long[primeCountMax];
  54.         primes[0] = 2;
  55.         primes[1] = 3;
  56.         primes[2] = 5;
  57.         length = 2;
  58.     }
  59.  
  60.     /**
  61.      * Prints out all primes in the prime cache one line at a time into the
  62.      * PrintStream.
  63.      *
  64.      * @param out
  65.      *            The PrintStream to print the prime cache out to.
  66.      */
  67.     public void print( PrintStream out )
  68.     {
  69.         for (int i = 0; i <= length; i++)
  70.         {
  71.             out.println( primes[i] );
  72.         }
  73.     }
  74.  
  75.     /**
  76.      * Determines whether the given number is prime.
  77.      *
  78.      * @param n
  79.      *            The number to check for primeness.
  80.      * @return True if the number is prime, otherwise false.
  81.      */
  82.     public boolean isPrime( long n )
  83.     {
  84.         // Does n exist in the prime cache?
  85.         if ( isQuickPrimeApplicable( n ) )
  86.         {
  87.             // Perform a quick search for n.
  88.             return isQuickPrime( n );
  89.         }
  90.  
  91.         long max = (long) Math.sqrt( n );
  92.  
  93.         // Ensure we have enough primes in the prime cache to determine whether
  94.         // or not n is a prime.
  95.         fillPrimes( max );
  96.  
  97.         // If itself is it's only factor, it's a prime.
  98.         return getFactor( n, max ) == n;
  99.     }
  100.  
  101.     /**
  102.      * Returns the first prime factor for n, or n if n is prime.
  103.      *
  104.      * @param n
  105.      *            The number to find the first prime factor of.
  106.      * @param nsqrt
  107.      *            The square-root of n.
  108.      * @return The first prime factor of n, or n if it's prime.
  109.      */
  110.     private long getFactor( long n, long nsqrt )
  111.     {
  112.         for (int i = 0; i <= length; i++)
  113.         {
  114.             long p = primes[i];
  115.  
  116.             if ( p > nsqrt )
  117.             {
  118.                 return n;
  119.             }
  120.  
  121.             if ( n % p == 0 )
  122.             {
  123.                 return p;
  124.             }
  125.         }
  126.  
  127.         return n;
  128.     }
  129.  
  130.     /**
  131.      * Ensures the prime cache has all primes up to some number max.
  132.      *
  133.      * @param max
  134.      *            The number the prime cache should encompass (have primes <=)
  135.      */
  136.     public void fillPrimes( long max )
  137.     {
  138.         while ( primes[length] < max )
  139.         {
  140.             long p = nextPrime( length );
  141.  
  142.             primes[++length] = p;
  143.         }
  144.     }
  145.  
  146.     /**
  147.      * Ensures the prime cache has at least primeCount primes.
  148.      *
  149.      * @param primeCount
  150.      *            The minimum number of primes the prime cache should have.
  151.      */
  152.     public void initialize( int primeCount )
  153.     {
  154.         --primeCount;
  155.  
  156.         while ( length < primeCount )
  157.         {
  158.             long p = nextPrime( length );
  159.  
  160.             primes[++length] = p;
  161.         }
  162.     }
  163.  
  164.     /**
  165.      * Computes the next prime in the sequence of all primes based on the prime
  166.      * at the given index in the prime cache.
  167.      *
  168.      * @param n
  169.      *            The index of a prime in the prime cache, the prime this method
  170.      *            returns will be the next prime in the sequence.
  171.      * @return The next prime in the sequence of primes.
  172.      */
  173.     public long nextPrime( int n )
  174.     {
  175.         long x = primes[n] + jump( n );
  176.  
  177.         while ( getFactor( x, (long) Math.sqrt( x ) ) != x )
  178.         {
  179.             x += jump( ++n );
  180.         }
  181.  
  182.         return x;
  183.     }
  184.  
  185.     /**
  186.      * A number is a quick prime if it exists in the currently generated cache
  187.      * of primes. This can efficiently be determined with a binary search.
  188.      *
  189.      * @param n
  190.      *            The prime to check.
  191.      * @return True if the given number exists in the prime cache.
  192.      */
  193.     public boolean isQuickPrime( long n )
  194.     {
  195.         return Arrays.binarySearch( primes, 0, length + 1, n ) >= 0;
  196.     }
  197.  
  198.     /**
  199.      * A number is quick prime applicable if there exists a prime in the cache
  200.      * that is larger than the provided number. This implies a search can be
  201.      * done in the array to determine if the provided number is a prime.
  202.      *
  203.      * @param n
  204.      *            The number to check for quick prime applicability.
  205.      * @return True if the number exists on the prime cache, otherwise false.
  206.      */
  207.     public boolean isQuickPrimeApplicable( long n )
  208.     {
  209.         return n <= primes[length];
  210.     }
  211.  
  212.     /**
  213.      * Given the index of a prime, return the jump (either 2 or 4) to use to
  214.      * approximate the next prime. The first 3 primes are excluded from this
  215.      * rule.
  216.      *
  217.      * @param x
  218.      *            The index of the prime.
  219.      * @return The amount to jump to the next possible prime.
  220.      */
  221.     private int jump( int x )
  222.     {
  223.         return ( 1 << ( ( x & 1 ) + 1 ) );
  224.     }
  225.  
  226.     /**
  227.      * Adds all prime factors of n to the given collection of numbers.
  228.      *
  229.      * @param n
  230.      *            The number to find all prime factors of.
  231.      * @param primeFactors
  232.      *            The collection to add prime factors to.
  233.      * @return The collection given.
  234.      */
  235.     public <D extends Collection<Long>> D factorize( long n, D primeFactors )
  236.     {
  237.         if ( isQuickPrimeApplicable( n ) && isQuickPrime( n ) )
  238.         {
  239.             return primeFactors;
  240.         }
  241.  
  242.         long max = (long) Math.sqrt( n );
  243.  
  244.         fillPrimes( max );
  245.  
  246.         while ( n != 1 )
  247.         {
  248.             long f = getFactor( n, max );
  249.  
  250.             primeFactors.add( f );
  251.  
  252.             n /= f;
  253.  
  254.             max = (long) Math.sqrt( n );
  255.         }
  256.  
  257.         return primeFactors;
  258.     }
  259.  
  260. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement