-
Notifications
You must be signed in to change notification settings - Fork 0
/
ConsecutivePrimes.java
119 lines (95 loc) · 4.24 KB
/
ConsecutivePrimes.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import java.util.*;
// Drew Boston, 3/3/19
/* This program finds the longest sequence of primes that sums to a prime number. For example, when run with the maximum integer = 100, the answer should be 41, as 41 is prime, and:
41 = 2 + 3 + 5 + 7 + 11 + 13, all of which are consecutive prime numbers. Please note that this finds
the longest sequence, not the one with the highest value.
This problem appears at this link: https://projecteuler.net/problem=50. */
public class ConsecutivePrimes{
private HashSet<Integer> primes; //list of all primes up to maxNum
private List<Integer> primesList; //used for quick indexing to check if sums are prime
private int maxNum; //maximum value (given by user input)
//constructor method
public ConsecutivePrimes(int n){
this.primes = new HashSet<Integer>();
this.primesList = new ArrayList<Integer>();
this.maxNum = n;
//add 2 to primes list (saves complexity for sieve of eros. later)
this.primes.add(2);
this.primesList.add(2);
}
//essentially the driver method
public void start(){
populateLists();
findConSum();
}
//prints the answer, number of terms, and the terms themselves to the console
public void printResults(int maxPrime, int maxCount, int startIndex, int endIndex){
System.out.printf("Answer is: %d\n", maxPrime);
System.out.printf("Which equals the sum of the following [%d] consecutive primes: \n", maxCount);
for(int i = startIndex; i <= endIndex; ++i){
if(i != endIndex)
System.out.printf(" %d, ", this.primesList.get(i));
else
System.out.printf(" %d\n", this.primesList.get(i));
}
}
//finds largest prime number that is also a sum of consecutive primes
//NOTE: possible optimizations - once we find the max length of consecutive primes seen so far,
//only consider lengths of a greater size - this would cut down on a lot of duplicate calculation...
public void findConSum(){
int maxPrime = 1;
int maxCount = 0;
int startIndex = 0;
int endIndex = 0;
for(int i = 0; i < primesList.size()-1; ++i){
int currentSum = this.primesList.get(i);
int count = 1;
for(int j = i+1; j < primesList.size(); ++j){
count++;
int nextVal = this.primesList.get(j);
currentSum += nextVal;
//to avoid int overflow, also cuts down complexity slightly
if(currentSum > this.maxNum)
break;
if(this.primes.contains(Integer.valueOf(currentSum)) && count > maxCount){
maxPrime = currentSum;
maxCount = count;
startIndex = i;
endIndex = j;
}
}
}
printResults(maxPrime, maxCount, startIndex, endIndex);
}
//non-threaded implementation of the sieve of eratosthenes (slow for large numbers)
public void findPrimes(List<Integer> allNums){
for(int i = 3; i <= maxNum; i+=2){
if (allNums.contains(Integer.valueOf(i))){
for(int j = 3 * i; j <= maxNum; j += (2*i)){
allNums.remove(Integer.valueOf(j));
}
}
}
}
//setup for sieve of eratosthenes, also populates primes list and hashmap
private void populateLists(){
List<Integer> allNums = new ArrayList<Integer>();
for(int i = 3; i <= maxNum; i+=2){
allNums.add(i);
}
this.findPrimes(allNums);
//populate primes / primesList with all primes
for(int i = 0; i < allNums.size(); ++i){
this.primes.add(allNums.get(i));
this.primesList.add(allNums.get(i));
}
}
//testing method, gets maximum integer from console / user input
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.printf("Enter the maximum Integer: ");
int n = sc.nextInt();
ConsecutivePrimes test = new ConsecutivePrimes(n);
test.start();
}
}