Sum of maximum primes as another prime below a million This is a project Euler Problem #50. Here is my solution with the problem.

/*
 * The prime 41, can be written as the sum of six consecutive primes: 41 = 2
 * + 3 + 5 + 7 + 11 + 13 This is the longest sum of consecutive primes that
 * adds to a prime below one-hundred. The longest sum of consecutive primes
 * below one-thousand that adds to a prime, contains 21 terms, and is equal
 * to 953. Which prime, below one-million, can be written as the sum of the
 * most consecutive primes?
 */
public static int get50() {
    int max = 21;
    int prime_max = 953;
    ArrayList&lt;Integer&gt; primes = Helper.getPrimes(1000000);
    for (int len = 21; len &lt;= primes.size(); len += 2) {
        long sum = 0;
        if (primes.get(len - 1) &gt; 1E6) {
            break;
        }
        if (sum &gt; 1E6) {
            return prime_max;
        }
        for (int k = 0; len + k - 1 &lt; primes.size(); k++) {

            if (k == 0) {
                for (int i = 0; i &lt; len; i++) {
                    sum += primes.get(i);
                }
            } else {
                sum += primes.get(len + k - 1) - primes.get(k - 1);
            }
            if (primes.get(len + k - 1) &gt; 1E6 || sum &gt; 1E6) {
                break;
            }
            if (Helper.isPrime((int) sum)) {
                if (len &gt; max) {
                    max = len;
                    prime_max = (int) sum;
                }
                break;
            }
        }
    }
    return prime_max;
}


Some things I wish to improve:


Time (currently over 40 seconds, Answer is 997651, Time taken 43.762743956 seconds)
If possible &amp;&amp; If reduces time Then using the new Java 8 methods.This would help me learn it too.
I've just switch my code from List&lt;Integer&gt; to int[] and the time went down from 19 to 11 seconds. This can be done using a loop or more simply with Guava's Ints.toArray().

While unboxing is cheap, you're needing it in the innermost loop. Which brings us to the point that there's no need for 3 nested loops, you're doing it right and I'm not. My code is faster, possibly because of my helper being faster...

public static int get50() {
    int max = 21;
    int prime_max = 953;
    ArrayList&lt;Integer&gt; primes = Helper.getPrimes(1000000);
    for (int len = 21; len &lt;= primes.size(); len += 2) {


Use some constants... all those magic numbers in code are a pain. Btw., optimizing via the given values 21 and 953 saves about nothing.

Sometimes, a loop with decreasing len could be faster, but not here as the resulting length is close to the beginning.

    if (primes.get(len - 1) &gt; 1E6) {


Again, constants please.

You could simplify the code by storing the partial sums and compute p[i] + p[i+1] + ... + p[j] simply as sum[j+1] - sum[i].

        if (primes.get(len + k - 1) &gt; 1E6 || sum &gt; 1E6) {


The first condition can never be true.

        if (Helper.isPrime((int) sum)) {
            if (len &gt; max) {
                max = len;
                prime_max = (int) sum;
            }
            break;
        }


I'm not sure about the break, but I guess that's because of the resulting sum being unique for a given length.


  If possible &amp;&amp; If reduces time Then using the new Java 8 methods.This would help me learn it too.


I strongly doubt, using Java 8 features will help, though using Java 8 surely can, because of the new optimizations.

I did some similar optimizations to my code now and the resulting time is 440 ms, where the initialization of my prime helper takes 438 ms (it always sieves up to 128 million and it's hard to change).



As we don't know why is my code faster, I'm adding my loop body taking just a few milliseconds:

for (int len=1; len&lt;primes.length; ++len) {
    for (int i=0; i&lt;primes.length-len; ++i) {
        final int j = i+len;
        if (i&gt;0 &amp;&amp; (len&amp;1) == 0) break;
        final long sum = sums[j] - sums[i];
        if (sum&gt;limit) break;
        if (!helper.isPrime(sum)) continue;
        best = len;
        result = sum;
        break;
    }
}