View difference between Paste ID: 7PxL3j67 and nDDSCBez
SHOW: | | - or go back to the newest paste.
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 );
23+
		Prime p = new Prime( 100000 );
24
25
		// Load 100,000 primes into cache
26
		long t0 = System.nanoTime();
27-
		p.initialize( 10000000 );
27+
		p.initialize( 100000 );
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
		// 100 primes
38
		p.print( System.out, 100 );
39
	}
40
41
	// The cache of prime numbers
42
	private long[] primes;
43
44
	// The index of the last prime number in the cache
45
	private int length;
46
47
	/**
48
	 * Instantiates a new Prime class with a maximum number of primes it can
49
	 * generate.
50
	 * 
51
	 * @param primeCountMax
52
	 *            The maximum number of primes this class may be able to store.
53
	 */
54
	public Prime( int primeCountMax )
55
	{
56
		primes = new long[primeCountMax];
57
		primes[0] = 2;
58
		primes[1] = 3;
59
		primes[2] = 5;
60
		length = 2;
61
	}
62
63
	/**
64
	 * Prints out all primes in the prime cache one line at a time into the
65
	 * PrintStream.
66
	 * 
67-
	public void print( PrintStream out )
67+
68
	 *            The PrintStream to print the prime cache out to.
69
	 */
70
	public void print( PrintStream out, int n )
71
	{
72
		for (int i = 0; i <= n; i++)
73
		{
74
			out.println( primes[i] );
75
		}
76
	}
77
78
	/**
79
	 * Determines whether the given number is prime.
80
	 * 
81
	 * @param n
82
	 *            The number to check for primeness.
83
	 * @return True if the number is prime, otherwise false.
84
	 */
85
	public boolean isPrime( long n )
86
	{
87
		// Does n exist in the prime cache?
88
		if ( isQuickPrimeApplicable( n ) )
89
		{
90
			// Perform a quick search for n.
91
			return isQuickPrime( n );
92
		}
93
94
		long max = (long) Math.sqrt( n );
95
96
		// Ensure we have enough primes in the prime cache to determine whether
97
		// or not n is a prime.
98
		fillPrimes( max );
99
100
		// If itself is it's only factor, it's a prime.
101
		return getFactor( n, max ) == n;
102
	}
103
104
	/**
105
	 * Returns the first prime factor for n, or n if n is prime.
106
	 * 
107
	 * @param n
108
	 *            The number to find the first prime factor of.
109
	 * @param nsqrt
110
	 *            The square-root of n.
111
	 * @return The first prime factor of n, or n if it's prime.
112
	 */
113
	private long getFactor( long n, long nsqrt )
114
	{
115
		for (int i = 0; i <= length; i++)
116
		{
117
			long p = primes[i];
118
119
			if ( p > nsqrt )
120
			{
121
				return n;
122
			}
123
124
			if ( n % p == 0 )
125
			{
126
				return p;
127
			}
128
		}
129
130
		return n;
131
	}
132
133
	/**
134
	 * Ensures the prime cache has all primes up to some number max.
135
	 * 
136
	 * @param max
137
	 *            The number the prime cache should encompass (have primes <=)
138
	 */
139
	public void fillPrimes( long max )
140
	{
141
		while ( primes[length] < max )
142
		{
143
			long p = nextPrime( length );
144
145
			primes[++length] = p;
146
		}
147
	}
148
149
	/**
150
	 * Ensures the prime cache has at least primeCount primes.
151
	 * 
152
	 * @param primeCount
153
	 *            The minimum number of primes the prime cache should have.
154
	 */
155
	public void initialize( int primeCount )
156
	{
157
		--primeCount;
158
159
		while ( length < primeCount )
160
		{
161
			long p = nextPrime( length );
162
163
			primes[++length] = p;
164
		}
165
	}
166
167
	/**
168
	 * Computes the next prime in the sequence of all primes based on the prime
169
	 * at the given index in the prime cache.
170
	 * 
171
	 * @param n
172
	 *            The index of a prime in the prime cache, the prime this method
173
	 *            returns will be the next prime in the sequence.
174
	 * @return The next prime in the sequence of primes.
175-
		long x = primes[n] + jump( n );
175+
176
	public long nextPrime( int n )
177
	{
178
		long x = primes[n] + 2;
179-
			x += jump( ++n );
179+
180
		while ( getFactor( x, (long) Math.sqrt( x ) ) != x )
181
		{
182
			x += 2;
183
		}
184
185
		return x;
186
	}
187
188
	/**
189
	 * A number is a quick prime if it exists in the currently generated cache
190
	 * of primes. This can efficiently be determined with a binary search.
191
	 * 
192
	 * @param n
193
	 *            The prime to check.
194
	 * @return True if the given number exists in the prime cache.
195
	 */
196
	public boolean isQuickPrime( long n )
197
	{
198
		return Arrays.binarySearch( primes, 0, length + 1, n ) >= 0;
199
	}
200
201
	/**
202
	 * A number is quick prime applicable if there exists a prime in the cache
203
	 * that is larger than the provided number. This implies a search can be
204
	 * done in the array to determine if the provided number is a prime.
205
	 * 
206
	 * @param n
207
	 *            The number to check for quick prime applicability.
208
	 * @return True if the number exists on the prime cache, otherwise false.
209
	 */
210
	public boolean isQuickPrimeApplicable( long n )
211
	{
212
		return n <= primes[length];
213-
	 * Given the index of a prime, return the jump (either 2 or 4) to use to
213+
214-
	 * approximate the next prime. The first 3 primes are excluded from this
214+
215-
	 * rule.
215+
216
	 * Adds all prime factors of n to the given collection of numbers.
217-
	 * @param x
217+
218-
	 *            The index of the prime.
218+
219-
	 * @return The amount to jump to the next possible prime.
219+
220
	 * @param primeFactors
221-
	private int jump( int x )
221+
222
	 * @return The collection given.
223-
		return ( 1 << ( ( x & 1 ) + 1 ) );
223+
224
	public <D extends Collection<Long>> D factorize( long n, D primeFactors )
225
	{
226
		if ( isQuickPrimeApplicable( n ) && isQuickPrime( n ) )
227
		{
228
			return primeFactors;
229
		}
230
231
		long max = (long) Math.sqrt( n );
232
233
		fillPrimes( max );
234
235
		while ( n != 1 )
236
		{
237
			long f = getFactor( n, max );
238
239
			primeFactors.add( f );
240
241
			n /= f;
242
243
			max = (long) Math.sqrt( n );
244
		}
245
246
		return primeFactors;
247
	}
248
249
}