diff --git a/src/main/java/com/thealgorithms/maths/SegmentedSieve.java b/src/main/java/com/thealgorithms/maths/SegmentedSieve.java new file mode 100644 index 000000000000..4a5805f328ae --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/SegmentedSieve.java @@ -0,0 +1,65 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SegmentedSieve { + + // fillPrime function fills primes from 2 to sqrt of high in chprime ArrayList + public static void fillPrime(ArrayList chprime, int high) { + boolean[] ck = new boolean[high + 1]; + Arrays.fill(ck, true); + ck[1] = false; + ck[0] = false; + + for (int i = 2; (i * i) <= high; i++) { + if (ck[i]) { + for (int j = i * i; j <= Math.sqrt(high); j = j + i) { + ck[j] = false; + } + } + } + for (int i = 2; i * i <= high; i++) { + if (ck[i]) { + chprime.add(i); + } + } + } + + // in segmented sieve we check for prime from range [low, high] + public static List segmentedSieve(int low, int high) { + if (low > high || low < 2) { + throw new IllegalArgumentException("Invalid range"); + } + + ArrayList chprime = new ArrayList<>(); + fillPrime(chprime, high); + + boolean[] prime = new boolean[high - low + 1]; + Arrays.fill(prime, true); + + for (int i : chprime) { + int lower = (low / i); + if (lower <= 1) { + lower = i + i; + } else if (low % i != 0) { + lower = (lower * i) + i; + } else { + lower = (lower * i); + } + for (int j = lower; j <= high; j = j + i) { + prime[j - low] = false; + } + } + + List result = new ArrayList<>(); + for (int i = low; i <= high; i++) { + if (prime[i - low]) { + result.add(i); + } + } + + return result; + } +} diff --git a/src/test/java/com/thealgorithms/maths/SegmentedSieveTest.java b/src/test/java/com/thealgorithms/maths/SegmentedSieveTest.java new file mode 100644 index 000000000000..3b3f2e64b90f --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/SegmentedSieveTest.java @@ -0,0 +1,40 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class SegmentedSieveTest { + + @Test + public void testPrimesInRange() { + List expectedPrimes = List.of(2, 3, 5, 7); + assertEquals(expectedPrimes, SegmentedSieve.segmentedSieve(2, 10)); + + List expectedPrimes2 = List.of(11, 13, 17, 19); + assertEquals(expectedPrimes2, SegmentedSieve.segmentedSieve(10, 20)); + } + + @Test + public void testLargeRange() { + List expectedPrimes = List.of(99991, 99997); + assertEquals(expectedPrimes, SegmentedSieve.segmentedSieve(99990, 100000)); + } + + @Test + public void testSinglePrime() { + List expectedPrime = List.of(7); + assertEquals(expectedPrime, SegmentedSieve.segmentedSieve(7, 7)); + + List expectedEmpty = new ArrayList<>(); + assertEquals(expectedEmpty, SegmentedSieve.segmentedSieve(8, 8)); + } + + @Test + public void testInvalidRange() { + assertThrows(IllegalArgumentException.class, () -> SegmentedSieve.segmentedSieve(-10, 10)); + assertThrows(IllegalArgumentException.class, () -> SegmentedSieve.segmentedSieve(20, 10)); // Invalid range + } +}