From 1564aab8744172d56348e7c3116e0160a7f067e5 Mon Sep 17 00:00:00 2001 From: Navadeep0007 <2400030007@kluniversity.in> Date: Sat, 15 Nov 2025 21:23:46 +0530 Subject: [PATCH 1/3] feat: add Sieve of Eratosthenes algorithm - Implement Sieve of Eratosthenes for finding prime numbers up to n - Add comprehensive unit tests with edge cases - Include JavaDoc documentation - Time complexity: O(n log log n) - Space complexity: O(n) Resolves #6939 --- .../maths/SieveOfEratosthenes.java | 108 ++++++++++-------- .../maths/SieveOfEratosthenesTest.java | 72 +++++++----- 2 files changed, 108 insertions(+), 72 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java b/src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java index f22d22e8c6af..977e7d3e4b12 100644 --- a/src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java +++ b/src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java @@ -1,66 +1,82 @@ package com.thealgorithms.maths; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; /** - * @brief utility class implementing Sieve of Eratosthenes + * Sieve of Eratosthenes Algorithm + * An efficient algorithm to find all prime numbers up to a given limit. + * + * Algorithm: + * 1. Create a boolean array of size n+1, initially all true + * 2. Mark 0 and 1 as not prime + * 3. For each number i from 2 to sqrt(n): + * - If i is still marked as prime + * - Mark all multiples of i (starting from i²) as not prime + * 4. Collect all numbers still marked as prime + * + * Time Complexity: O(n log log n) + * Space Complexity: O(n) + * + * @author Navadeep0007 + * @see Sieve of Eratosthenes */ public final class SieveOfEratosthenes { + private SieveOfEratosthenes() { + // Utility class, prevent instantiation } - - private static void checkInput(int n) { - if (n <= 0) { - throw new IllegalArgumentException("n must be positive."); + + /** + * Finds all prime numbers up to n using the Sieve of Eratosthenes algorithm + * + * @param n the upper limit (inclusive) + * @return a list of all prime numbers from 2 to n + * @throws IllegalArgumentException if n is negative + */ + public static List findPrimes(int n) { + if (n < 0) { + throw new IllegalArgumentException("Input must be non-negative"); } - } - - private static Type[] sievePrimesTill(int n) { - checkInput(n); - Type[] isPrimeArray = new Type[n + 1]; - Arrays.fill(isPrimeArray, Type.PRIME); - isPrimeArray[0] = Type.NOT_PRIME; - isPrimeArray[1] = Type.NOT_PRIME; - - double cap = Math.sqrt(n); - for (int i = 2; i <= cap; i++) { - if (isPrimeArray[i] == Type.PRIME) { - for (int j = 2; i * j <= n; j++) { - isPrimeArray[i * j] = Type.NOT_PRIME; + + if (n < 2) { + return new ArrayList<>(); + } + + // Create boolean array, initially all true + boolean[] isPrime = new boolean[n + 1]; + for (int i = 2; i <= n; i++) { + isPrime[i] = true; + } + + // Sieve process + for (int i = 2; i * i <= n; i++) { + if (isPrime[i]) { + // Mark all multiples of i as not prime + for (int j = i * i; j <= n; j += i) { + isPrime[j] = false; } } } - return isPrimeArray; - } - - private static int countPrimes(Type[] isPrimeArray) { - return (int) Arrays.stream(isPrimeArray).filter(element -> element == Type.PRIME).count(); - } - - private static int[] extractPrimes(Type[] isPrimeArray) { - int numberOfPrimes = countPrimes(isPrimeArray); - int[] primes = new int[numberOfPrimes]; - int primeIndex = 0; - for (int curNumber = 0; curNumber < isPrimeArray.length; ++curNumber) { - if (isPrimeArray[curNumber] == Type.PRIME) { - primes[primeIndex++] = curNumber; + + // Collect all prime numbers + List primes = new ArrayList<>(); + for (int i = 2; i <= n; i++) { + if (isPrime[i]) { + primes.add(i); } } + return primes; } - + /** - * @brief finds all of the prime numbers up to the given upper (inclusive) limit - * @param n upper (inclusive) limit - * @exception IllegalArgumentException n is non-positive - * @return the array of all primes up to the given number (inclusive) + * Counts the number of prime numbers up to n + * + * @param n the upper limit (inclusive) + * @return count of prime numbers from 2 to n */ - public static int[] findPrimesTill(int n) { - return extractPrimes(sievePrimesTill(n)); - } - - private enum Type { - PRIME, - NOT_PRIME, + public static int countPrimes(int n) { + return findPrimes(n).size(); } } diff --git a/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java b/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java index ebbd5df712fc..92b4d0c6588b 100644 --- a/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java +++ b/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java @@ -1,46 +1,66 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.Test; +/** + * Test cases for Sieve of Eratosthenes algorithm + * + * @author Navadeep0007 + */ class SieveOfEratosthenesTest { + @Test - public void testfFindPrimesTill1() { - assertArrayEquals(new int[] {}, SieveOfEratosthenes.findPrimesTill(1)); + void testPrimesUpTo10() { + List expected = Arrays.asList(2, 3, 5, 7); + assertEquals(expected, SieveOfEratosthenes.findPrimes(10)); } - + @Test - public void testfFindPrimesTill2() { - assertArrayEquals(new int[] {2}, SieveOfEratosthenes.findPrimesTill(2)); + void testPrimesUpTo30() { + List expected = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29); + assertEquals(expected, SieveOfEratosthenes.findPrimes(30)); } - + @Test - public void testfFindPrimesTill4() { - var primesTill4 = new int[] {2, 3}; - assertArrayEquals(primesTill4, SieveOfEratosthenes.findPrimesTill(3)); - assertArrayEquals(primesTill4, SieveOfEratosthenes.findPrimesTill(4)); + void testPrimesUpTo2() { + List expected = Arrays.asList(2); + assertEquals(expected, SieveOfEratosthenes.findPrimes(2)); } - + @Test - public void testfFindPrimesTill40() { - var primesTill40 = new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; - assertArrayEquals(primesTill40, SieveOfEratosthenes.findPrimesTill(37)); - assertArrayEquals(primesTill40, SieveOfEratosthenes.findPrimesTill(38)); - assertArrayEquals(primesTill40, SieveOfEratosthenes.findPrimesTill(39)); - assertArrayEquals(primesTill40, SieveOfEratosthenes.findPrimesTill(40)); + void testPrimesUpTo1() { + assertTrue(SieveOfEratosthenes.findPrimes(1).isEmpty()); } - + @Test - public void testfFindPrimesTill240() { - var primesTill240 = new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239}; - assertArrayEquals(primesTill240, SieveOfEratosthenes.findPrimesTill(239)); - assertArrayEquals(primesTill240, SieveOfEratosthenes.findPrimesTill(240)); + void testPrimesUpTo0() { + assertTrue(SieveOfEratosthenes.findPrimes(0).isEmpty()); } - + + @Test + void testNegativeInput() { + assertThrows(IllegalArgumentException.class, () -> { + SieveOfEratosthenes.findPrimes(-1); + }); + } + + @Test + void testCountPrimes() { + assertEquals(4, SieveOfEratosthenes.countPrimes(10)); + assertEquals(25, SieveOfEratosthenes.countPrimes(100)); + } + @Test - public void testFindPrimesTillThrowsExceptionForNonPositiveInput() { - assertThrows(IllegalArgumentException.class, () -> SieveOfEratosthenes.findPrimesTill(0)); + void testLargeNumber() { + List primes = SieveOfEratosthenes.findPrimes(1000); + assertEquals(168, primes.size()); // There are 168 primes up to 1000 + assertEquals(2, primes.get(0)); // First prime + assertEquals(997, primes.get(primes.size() - 1)); // Last prime up to 1000 } } From f582ee62553d03b990ad3edc833c66a716d5c942 Mon Sep 17 00:00:00 2001 From: Navadeep0007 <2400030007@kluniversity.in> Date: Sat, 15 Nov 2025 23:27:22 +0530 Subject: [PATCH 2/3] fix: remove trailing spaces --- .../maths/SieveOfEratosthenes.java | 26 +++++++++---------- .../maths/SieveOfEratosthenesTest.java | 18 ++++++------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java b/src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java index 977e7d3e4b12..5a15c4201a15 100644 --- a/src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java +++ b/src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java @@ -6,7 +6,7 @@ /** * Sieve of Eratosthenes Algorithm * An efficient algorithm to find all prime numbers up to a given limit. - * + * * Algorithm: * 1. Create a boolean array of size n+1, initially all true * 2. Mark 0 and 1 as not prime @@ -14,22 +14,22 @@ * - If i is still marked as prime * - Mark all multiples of i (starting from i²) as not prime * 4. Collect all numbers still marked as prime - * + * * Time Complexity: O(n log log n) * Space Complexity: O(n) - * + * * @author Navadeep0007 * @see Sieve of Eratosthenes */ public final class SieveOfEratosthenes { - + private SieveOfEratosthenes() { // Utility class, prevent instantiation } - + /** * Finds all prime numbers up to n using the Sieve of Eratosthenes algorithm - * + * * @param n the upper limit (inclusive) * @return a list of all prime numbers from 2 to n * @throws IllegalArgumentException if n is negative @@ -38,17 +38,17 @@ public static List findPrimes(int n) { if (n < 0) { throw new IllegalArgumentException("Input must be non-negative"); } - + if (n < 2) { return new ArrayList<>(); } - + // Create boolean array, initially all true boolean[] isPrime = new boolean[n + 1]; for (int i = 2; i <= n; i++) { isPrime[i] = true; } - + // Sieve process for (int i = 2; i * i <= n; i++) { if (isPrime[i]) { @@ -58,7 +58,7 @@ public static List findPrimes(int n) { } } } - + // Collect all prime numbers List primes = new ArrayList<>(); for (int i = 2; i <= n; i++) { @@ -66,13 +66,13 @@ public static List findPrimes(int n) { primes.add(i); } } - + return primes; } - + /** * Counts the number of prime numbers up to n - * + * * @param n the upper limit (inclusive) * @return count of prime numbers from 2 to n */ diff --git a/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java b/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java index 92b4d0c6588b..5a460edc95bd 100644 --- a/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java +++ b/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java @@ -10,52 +10,52 @@ /** * Test cases for Sieve of Eratosthenes algorithm - * + * * @author Navadeep0007 */ class SieveOfEratosthenesTest { - + @Test void testPrimesUpTo10() { List expected = Arrays.asList(2, 3, 5, 7); assertEquals(expected, SieveOfEratosthenes.findPrimes(10)); } - + @Test void testPrimesUpTo30() { List expected = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29); assertEquals(expected, SieveOfEratosthenes.findPrimes(30)); } - + @Test void testPrimesUpTo2() { List expected = Arrays.asList(2); assertEquals(expected, SieveOfEratosthenes.findPrimes(2)); } - + @Test void testPrimesUpTo1() { assertTrue(SieveOfEratosthenes.findPrimes(1).isEmpty()); } - + @Test void testPrimesUpTo0() { assertTrue(SieveOfEratosthenes.findPrimes(0).isEmpty()); } - + @Test void testNegativeInput() { assertThrows(IllegalArgumentException.class, () -> { SieveOfEratosthenes.findPrimes(-1); }); } - + @Test void testCountPrimes() { assertEquals(4, SieveOfEratosthenes.countPrimes(10)); assertEquals(25, SieveOfEratosthenes.countPrimes(100)); } - + @Test void testLargeNumber() { List primes = SieveOfEratosthenes.findPrimes(1000); From 5243b0f5475d1b49249df6d486df91a9cbdc2e78 Mon Sep 17 00:00:00 2001 From: Navadeep0007 <2400030007@kluniversity.in> Date: Sat, 15 Nov 2025 23:32:15 +0530 Subject: [PATCH 3/3] fix: apply clang-format --- .../java/com/thealgorithms/maths/SieveOfEratosthenesTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java b/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java index 5a460edc95bd..5d491a493ee7 100644 --- a/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java +++ b/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java @@ -45,9 +45,7 @@ void testPrimesUpTo0() { @Test void testNegativeInput() { - assertThrows(IllegalArgumentException.class, () -> { - SieveOfEratosthenes.findPrimes(-1); - }); + assertThrows(IllegalArgumentException.class, () -> { SieveOfEratosthenes.findPrimes(-1); }); } @Test