I signed up on codewars in March and I have finished a number of challenges. I am encountering difficulty with the following. The name is Prime Streaming (PG-13) and is highlighted below. Create an endless stream of prime numbers - a bit like IntStream.of(2, 3, 5, 7, 11, 13, 17), but infinite. The stream must be able to produce a million primes in a few seconds.
This is the code that I am using in an attempt to solve the problem.
import java.util.stream.IntStream;
import java.util.ArrayList;
import java.util.Arrays;
public class Primes {
private static ArrayList<Integer> primes = new ArrayList<Integer>();
public static IntStream stream() {
return IntStream.iterate(2,i->i+1).filter(x->isPrime(x)).limit(1000000);
}
private static boolean isPrime(int n) {
if(n<2) return false;
for (int i = 0; i < primes.size();i++){
int x = primes . get( i );
if ( n % x ==0 ) return false;
}
primes.add(n);
return true;
}
}
These are the tests that the code must pass in order for the challenge to be completed.
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
public class PrimesTest {
@Test
public void test_0_10() {
test(0, 10, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
}
@Test
public void test_10_10() {
test(10, 10, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71);
}
@Test
public void test_100_10() {
test(100, 10, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601);
}
@Test
public void test_1000_10() {
test(1000, 10, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017);
}
private void test(int skip, int limit, int... expect) {
int[] found = Primes.stream().skip(skip).limit(limit).toArray();
assertArrayEquals(expect, found);
}
}
My issue is this. The code will pass the first test but not the others. I have noticed that the number produced is a prime but it is one further down in the series. Apparently , everytime Primes.stream() is called, instead of starting from scratch and creating a new one, it continues from the prime number in the last test. For each further test, using the first set of primes , it skips a 10 extra and calls a number . The first test called is test_0_10 and it correctly returns 29. The second test called is test_1000_10 and it returns 8039 instead of 7927. The third test called is test_10_10 and it calls 8221 instead of 31. I know streams are lazily evaluated and suspect that this is the problem. Can someone please help?
See my description above for what I tried and the results
You might have to create the
ArrayListfor every call to stream to prevent its previous state interfering with new result. Something like below should fix your issue: