From 5493aa534b87b97d46b87470207ebfd1e1f24313 Mon Sep 17 00:00:00 2001 From: shriramthebeast Date: Thu, 2 Oct 2025 11:24:53 +0530 Subject: [PATCH 01/10] Add Sum of Squares algorithm implementation --- .../com/thealgorithms/maths/SumOfSquares.java | 40 +++++++++++ .../thealgorithms/maths/SumOfSquaresTest.java | 66 +++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 src/main/java/com/thealgorithms/maths/SumOfSquares.java create mode 100644 src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java diff --git a/src/main/java/com/thealgorithms/maths/SumOfSquares.java b/src/main/java/com/thealgorithms/maths/SumOfSquares.java new file mode 100644 index 000000000000..66aabb315ef2 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/SumOfSquares.java @@ -0,0 +1,40 @@ +package com.thealgorithms.maths; + +/** + * Implementation of Lagrange's Four Square Theorem + * Find minimum number of perfect squares that sum to given number + * @author BEASTSHRIRAM + */ +public final class SumOfSquares { + + private SumOfSquares() { + // Utility class + } + + /** + * Find minimum number of perfect squares that sum to n + * @param n the target number + * @return minimum number of squares needed + */ + public static int minSquares(int n) { + if (isPerfectSquare(n)) return 1; + + for (int i = 1; i * i <= n; i++) { + int remaining = n - i * i; + if (isPerfectSquare(remaining)) return 2; + } + + // Legendre's three-square theorem + int temp = n; + while (temp % 4 == 0) temp /= 4; + if (temp % 8 == 7) return 4; + + return 3; + } + + private static boolean isPerfectSquare(int n) { + if (n < 0) return false; + int root = (int) Math.sqrt(n); + return root * root == n; + } +} \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java b/src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java new file mode 100644 index 000000000000..50ab43a8ff39 --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java @@ -0,0 +1,66 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +/** + * Test class for SumOfSquares + * @author BEASTSHRIRAM + */ +class SumOfSquaresTest { + + @Test + void testPerfectSquares() { + // Perfect squares should return 1 + assertEquals(1, SumOfSquares.minSquares(1)); // 1^2 + assertEquals(1, SumOfSquares.minSquares(4)); // 2^2 + assertEquals(1, SumOfSquares.minSquares(9)); // 3^2 + assertEquals(1, SumOfSquares.minSquares(16)); // 4^2 + assertEquals(1, SumOfSquares.minSquares(25)); // 5^2 + } + + @Test + void testTwoSquares() { + // Numbers that can be expressed as sum of two squares + assertEquals(2, SumOfSquares.minSquares(2)); // 1^2 + 1^2 + assertEquals(2, SumOfSquares.minSquares(5)); // 1^2 + 2^2 + assertEquals(2, SumOfSquares.minSquares(8)); // 2^2 + 2^2 + assertEquals(2, SumOfSquares.minSquares(10)); // 1^2 + 3^2 + assertEquals(2, SumOfSquares.minSquares(13)); // 2^2 + 3^2 + } + + @Test + void testThreeSquares() { + // Numbers that require exactly three squares + assertEquals(3, SumOfSquares.minSquares(3)); // 1^2 + 1^2 + 1^2 + assertEquals(3, SumOfSquares.minSquares(6)); // 1^2 + 1^2 + 2^2 + assertEquals(3, SumOfSquares.minSquares(11)); // 1^2 + 1^2 + 3^2 + assertEquals(3, SumOfSquares.minSquares(12)); // 2^2 + 2^2 + 2^2 + assertEquals(3, SumOfSquares.minSquares(14)); // 1^2 + 2^2 + 3^2 + } + + @Test + void testFourSquares() { + // Numbers that require exactly four squares (form 4^a * (8b + 7)) + assertEquals(4, SumOfSquares.minSquares(7)); // 1^2 + 1^2 + 1^2 + 2^2 + assertEquals(4, SumOfSquares.minSquares(15)); // 1^2 + 1^2 + 2^2 + 3^2 + assertEquals(4, SumOfSquares.minSquares(23)); // 1^2 + 1^2 + 3^2 + 3^2 + assertEquals(4, SumOfSquares.minSquares(28)); // 4 * 7, so needs 4 squares + assertEquals(4, SumOfSquares.minSquares(31)); // 1^2 + 2^2 + 3^2 + 3^2 + } + + @Test + void testLargerNumbers() { + // Test some larger numbers + assertEquals(1, SumOfSquares.minSquares(100)); // 10^2 + assertEquals(2, SumOfSquares.minSquares(65)); // 1^2 + 8^2 + assertEquals(3, SumOfSquares.minSquares(19)); // 1^2 + 3^2 + 3^2 + assertEquals(4, SumOfSquares.minSquares(60)); // 4 * 15, and 15 = 8*1 + 7 + } + + @Test + void testEdgeCases() { + // Test edge case + assertEquals(1, SumOfSquares.minSquares(0)); // 0^2 + } +} \ No newline at end of file From 3e9f0399de5b1c29410a0f69978ac6cdbeccc59e Mon Sep 17 00:00:00 2001 From: shriramthebeast Date: Thu, 2 Oct 2025 11:29:36 +0530 Subject: [PATCH 02/10] Format code and add Wikipedia URL for Lagrange's theorem --- .../com/thealgorithms/maths/SumOfSquares.java | 35 +++++++++---- .../thealgorithms/maths/SumOfSquaresTest.java | 50 ++++++++++--------- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/SumOfSquares.java b/src/main/java/com/thealgorithms/maths/SumOfSquares.java index 66aabb315ef2..bdae6665edc3 100644 --- a/src/main/java/com/thealgorithms/maths/SumOfSquares.java +++ b/src/main/java/com/thealgorithms/maths/SumOfSquares.java @@ -3,37 +3,50 @@ /** * Implementation of Lagrange's Four Square Theorem * Find minimum number of perfect squares that sum to given number + * + * @see Lagrange's Four Square Theorem * @author BEASTSHRIRAM */ public final class SumOfSquares { - + private SumOfSquares() { // Utility class } - + /** * Find minimum number of perfect squares that sum to n + * * @param n the target number * @return minimum number of squares needed */ public static int minSquares(int n) { - if (isPerfectSquare(n)) return 1; - + if (isPerfectSquare(n)) { + return 1; + } + for (int i = 1; i * i <= n; i++) { int remaining = n - i * i; - if (isPerfectSquare(remaining)) return 2; + if (isPerfectSquare(remaining)) { + return 2; + } } - + // Legendre's three-square theorem int temp = n; - while (temp % 4 == 0) temp /= 4; - if (temp % 8 == 7) return 4; - + while (temp % 4 == 0) { + temp /= 4; + } + if (temp % 8 == 7) { + return 4; + } + return 3; } - + private static boolean isPerfectSquare(int n) { - if (n < 0) return false; + if (n < 0) { + return false; + } int root = (int) Math.sqrt(n); return root * root == n; } diff --git a/src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java b/src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java index 50ab43a8ff39..a87b0f6ad145 100644 --- a/src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java +++ b/src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java @@ -1,10 +1,12 @@ package com.thealgorithms.maths; import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.Test; /** * Test class for SumOfSquares + * * @author BEASTSHRIRAM */ class SumOfSquaresTest { @@ -12,55 +14,55 @@ class SumOfSquaresTest { @Test void testPerfectSquares() { // Perfect squares should return 1 - assertEquals(1, SumOfSquares.minSquares(1)); // 1^2 - assertEquals(1, SumOfSquares.minSquares(4)); // 2^2 - assertEquals(1, SumOfSquares.minSquares(9)); // 3^2 - assertEquals(1, SumOfSquares.minSquares(16)); // 4^2 - assertEquals(1, SumOfSquares.minSquares(25)); // 5^2 + assertEquals(1, SumOfSquares.minSquares(1)); // 1^2 + assertEquals(1, SumOfSquares.minSquares(4)); // 2^2 + assertEquals(1, SumOfSquares.minSquares(9)); // 3^2 + assertEquals(1, SumOfSquares.minSquares(16)); // 4^2 + assertEquals(1, SumOfSquares.minSquares(25)); // 5^2 } @Test void testTwoSquares() { // Numbers that can be expressed as sum of two squares - assertEquals(2, SumOfSquares.minSquares(2)); // 1^2 + 1^2 - assertEquals(2, SumOfSquares.minSquares(5)); // 1^2 + 2^2 - assertEquals(2, SumOfSquares.minSquares(8)); // 2^2 + 2^2 - assertEquals(2, SumOfSquares.minSquares(10)); // 1^2 + 3^2 - assertEquals(2, SumOfSquares.minSquares(13)); // 2^2 + 3^2 + assertEquals(2, SumOfSquares.minSquares(2)); // 1^2 + 1^2 + assertEquals(2, SumOfSquares.minSquares(5)); // 1^2 + 2^2 + assertEquals(2, SumOfSquares.minSquares(8)); // 2^2 + 2^2 + assertEquals(2, SumOfSquares.minSquares(10)); // 1^2 + 3^2 + assertEquals(2, SumOfSquares.minSquares(13)); // 2^2 + 3^2 } @Test void testThreeSquares() { // Numbers that require exactly three squares - assertEquals(3, SumOfSquares.minSquares(3)); // 1^2 + 1^2 + 1^2 - assertEquals(3, SumOfSquares.minSquares(6)); // 1^2 + 1^2 + 2^2 - assertEquals(3, SumOfSquares.minSquares(11)); // 1^2 + 1^2 + 3^2 - assertEquals(3, SumOfSquares.minSquares(12)); // 2^2 + 2^2 + 2^2 - assertEquals(3, SumOfSquares.minSquares(14)); // 1^2 + 2^2 + 3^2 + assertEquals(3, SumOfSquares.minSquares(3)); // 1^2 + 1^2 + 1^2 + assertEquals(3, SumOfSquares.minSquares(6)); // 1^2 + 1^2 + 2^2 + assertEquals(3, SumOfSquares.minSquares(11)); // 1^2 + 1^2 + 3^2 + assertEquals(3, SumOfSquares.minSquares(12)); // 2^2 + 2^2 + 2^2 + assertEquals(3, SumOfSquares.minSquares(14)); // 1^2 + 2^2 + 3^2 } @Test void testFourSquares() { // Numbers that require exactly four squares (form 4^a * (8b + 7)) - assertEquals(4, SumOfSquares.minSquares(7)); // 1^2 + 1^2 + 1^2 + 2^2 - assertEquals(4, SumOfSquares.minSquares(15)); // 1^2 + 1^2 + 2^2 + 3^2 - assertEquals(4, SumOfSquares.minSquares(23)); // 1^2 + 1^2 + 3^2 + 3^2 - assertEquals(4, SumOfSquares.minSquares(28)); // 4 * 7, so needs 4 squares - assertEquals(4, SumOfSquares.minSquares(31)); // 1^2 + 2^2 + 3^2 + 3^2 + assertEquals(4, SumOfSquares.minSquares(7)); // 1^2 + 1^2 + 1^2 + 2^2 + assertEquals(4, SumOfSquares.minSquares(15)); // 1^2 + 1^2 + 2^2 + 3^2 + assertEquals(4, SumOfSquares.minSquares(23)); // 1^2 + 1^2 + 3^2 + 3^2 + assertEquals(4, SumOfSquares.minSquares(28)); // 4 * 7, so needs 4 squares + assertEquals(4, SumOfSquares.minSquares(31)); // 1^2 + 2^2 + 3^2 + 3^2 } @Test void testLargerNumbers() { // Test some larger numbers assertEquals(1, SumOfSquares.minSquares(100)); // 10^2 - assertEquals(2, SumOfSquares.minSquares(65)); // 1^2 + 8^2 - assertEquals(3, SumOfSquares.minSquares(19)); // 1^2 + 3^2 + 3^2 - assertEquals(4, SumOfSquares.minSquares(60)); // 4 * 15, and 15 = 8*1 + 7 + assertEquals(2, SumOfSquares.minSquares(65)); // 1^2 + 8^2 + assertEquals(3, SumOfSquares.minSquares(19)); // 1^2 + 3^2 + 3^2 + assertEquals(4, SumOfSquares.minSquares(60)); // 4 * 15, and 15 = 8*1 + 7 } @Test void testEdgeCases() { // Test edge case - assertEquals(1, SumOfSquares.minSquares(0)); // 0^2 + assertEquals(1, SumOfSquares.minSquares(0)); // 0^2 } } \ No newline at end of file From e71008fa3f8d1d94e6b3b7653b1d4590f3260701 Mon Sep 17 00:00:00 2001 From: shriramthebeast Date: Thu, 2 Oct 2025 11:42:30 +0530 Subject: [PATCH 03/10] Fixed clang-format issues --- src/main/java/com/thealgorithms/maths/SumOfSquares.java | 2 +- src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/SumOfSquares.java b/src/main/java/com/thealgorithms/maths/SumOfSquares.java index bdae6665edc3..c050d5a75f7b 100644 --- a/src/main/java/com/thealgorithms/maths/SumOfSquares.java +++ b/src/main/java/com/thealgorithms/maths/SumOfSquares.java @@ -50,4 +50,4 @@ private static boolean isPerfectSquare(int n) { int root = (int) Math.sqrt(n); return root * root == n; } -} \ No newline at end of file +} diff --git a/src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java b/src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java index a87b0f6ad145..834fe61a049e 100644 --- a/src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java +++ b/src/test/java/com/thealgorithms/maths/SumOfSquaresTest.java @@ -65,4 +65,4 @@ void testEdgeCases() { // Test edge case assertEquals(1, SumOfSquares.minSquares(0)); // 0^2 } -} \ No newline at end of file +} From db58f8028b7dd4ec2ba31e17f38c0e9a719ae9d8 Mon Sep 17 00:00:00 2001 From: shriramthebeast Date: Thu, 2 Oct 2025 19:07:46 +0530 Subject: [PATCH 04/10] Added Mo's Algorithm and DiceThrower recursive algorithms - Mo's Algorithm: Square root decomposition for offline range queries(Imp in CP) - DiceThrower: Recursive backtracking for dice combinations(very imp) - Both algorithms include comprehensive test suites - Formatted with clang-format and i follow contribution guidelines --- .../thealgorithms/others/MosAlgorithm.java | 260 ++++++++++++++++++ .../thealgorithms/recursion/DiceThrower.java | 113 ++++++++ .../others/MosAlgorithmTest.java | 178 ++++++++++++ .../recursion/DiceThrowerTest.java | 127 +++++++++ 4 files changed, 678 insertions(+) create mode 100644 src/main/java/com/thealgorithms/others/MosAlgorithm.java create mode 100644 src/main/java/com/thealgorithms/recursion/DiceThrower.java create mode 100644 src/test/java/com/thealgorithms/others/MosAlgorithmTest.java create mode 100644 src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java diff --git a/src/main/java/com/thealgorithms/others/MosAlgorithm.java b/src/main/java/com/thealgorithms/others/MosAlgorithm.java new file mode 100644 index 000000000000..847c4e9b1bf9 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/MosAlgorithm.java @@ -0,0 +1,260 @@ +package com.thealgorithms.others; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * Mo's Algorithm (Square Root Decomposition) for offline range queries + * + * Mo's Algorithm is used to answer range queries efficiently when: + * 1. Queries can be processed offline (all queries known beforehand) + * 2. We can efficiently add/remove elements from current range + * 3. The problem has optimal substructure for range operations + * + * Time Complexity: O((N + Q) * sqrt(N)) where N = array size, Q = number of queries + * Space Complexity: O(N + Q) + * + * @see Mo's Algorithm + * @author BEASTSHRIRAM + */ +public final class MosAlgorithm { + + /** + * Query structure to store range queries + */ + public static class Query { + public final int left; + public final int right; + public final int index; // Original index of query + public int result; // Result of the query + + public Query(int left, int right, int index) { + this.left = left; + this.right = right; + this.index = index; + this.result = 0; + } + } + + private MosAlgorithm() { + // Utility class + } + + /** + * Solves range sum queries using Mo's Algorithm + * + * @param arr the input array + * @param queries array of queries to process + * @return array of results corresponding to each query + */ + public static int[] solveRangeSumQueries(int[] arr, Query[] queries) { + if (arr == null || queries == null || arr.length == 0) { + return new int[0]; + } + + int n = arr.length; + int blockSize = (int) Math.sqrt(n); + + // Sort queries using Mo's ordering + Arrays.sort(queries, new MoComparator(blockSize)); + + // Initialize variables for current range + int currentLeft = 0; + int currentRight = -1; + int currentSum = 0; + + // Process each query + for (Query query : queries) { + // Expand or shrink the current range to match query range + + // Expand right boundary + while (currentRight < query.right) { + currentRight++; + currentSum += arr[currentRight]; + } + + // Shrink right boundary + while (currentRight > query.right) { + currentSum -= arr[currentRight]; + currentRight--; + } + + // Expand left boundary + while (currentLeft < query.left) { + currentSum -= arr[currentLeft]; + currentLeft++; + } + + // Shrink left boundary + while (currentLeft > query.left) { + currentLeft--; + currentSum += arr[currentLeft]; + } + + // Store the result + query.result = currentSum; + } + + // Extract results in original query order + int[] results = new int[queries.length]; + for (Query query : queries) { + results[query.index] = query.result; + } + + return results; + } + + /** + * Solves range frequency queries using Mo's Algorithm + * Example: Count occurrences of a specific value in range [L, R] + * + * @param arr the input array + * @param queries array of queries to process + * @param targetValue the value to count in each range + * @return array of results corresponding to each query + */ + public static int[] solveRangeFrequencyQueries(int[] arr, Query[] queries, int targetValue) { + if (arr == null || queries == null || arr.length == 0) { + return new int[0]; + } + + int n = arr.length; + int blockSize = (int) Math.sqrt(n); + + // Sort queries using Mo's ordering + Arrays.sort(queries, new MoComparator(blockSize)); + + // Initialize variables for current range + int currentLeft = 0; + int currentRight = -1; + int currentCount = 0; + + // Process each query + for (Query query : queries) { + // Expand right boundary + while (currentRight < query.right) { + currentRight++; + if (arr[currentRight] == targetValue) { + currentCount++; + } + } + + // Shrink right boundary + while (currentRight > query.right) { + if (arr[currentRight] == targetValue) { + currentCount--; + } + currentRight--; + } + + // Expand left boundary + while (currentLeft < query.left) { + if (arr[currentLeft] == targetValue) { + currentCount--; + } + currentLeft++; + } + + // Shrink left boundary + while (currentLeft > query.left) { + currentLeft--; + if (arr[currentLeft] == targetValue) { + currentCount++; + } + } + + // Store the result + query.result = currentCount; + } + + // Extract results in original query order + int[] results = new int[queries.length]; + for (Query query : queries) { + results[query.index] = query.result; + } + + return results; + } + + /** + * Comparator for Mo's Algorithm query ordering + * Queries are sorted by block of left endpoint, then by right endpoint + */ + private static class MoComparator implements Comparator { + private final int blockSize; + + public MoComparator(int blockSize) { + this.blockSize = blockSize; + } + + @Override + public int compare(Query a, Query b) { + int blockA = a.left / blockSize; + int blockB = b.left / blockSize; + + if (blockA != blockB) { + return Integer.compare(blockA, blockB); + } + + // For odd blocks, sort right in ascending order + // For even blocks, sort right in descending order (optimization) + if (blockA % 2 == 1) { + return Integer.compare(a.right, b.right); + } else { + return Integer.compare(b.right, a.right); + } + } + } + + /** + * Demo method showing usage of Mo's Algorithm + * + * @param args command line arguments + */ + public static void main(String[] args) { + // Example: Range sum queries + int[] arr = {1, 3, 5, 2, 7, 6, 3, 1, 4, 8}; + + Query[] queries = { + new Query(0, 2, 0), // Sum of elements from index 0 to 2: 1+3+5 = 9 + new Query(1, 4, 1), // Sum of elements from index 1 to 4: 3+5+2+7 = 17 + new Query(2, 6, 2), // Sum of elements from index 2 to 6: 5+2+7+6+3 = 23 + new Query(3, 8, 3) // Sum of elements from index 3 to 8: 2+7+6+3+1+4 = 23 + }; + + System.out.println("Array: " + Arrays.toString(arr)); + System.out.println("Range Sum Queries:"); + + // Store original queries for display + Query[] originalQueries = new Query[queries.length]; + for (int i = 0; i < queries.length; i++) { + originalQueries[i] = new Query(queries[i].left, queries[i].right, queries[i].index); + } + + int[] results = solveRangeSumQueries(arr, queries); + + for (int i = 0; i < originalQueries.length; i++) { + System.out.printf("Query %d: Sum of range [%d, %d] = %d%n", i, originalQueries[i].left, originalQueries[i].right, results[i]); + } + + // Example: Range frequency queries + System.out.println("\nRange Frequency Queries (count of value 3):"); + Query[] freqQueries = { + new Query(0, 5, 0), // Count of 3 in range [0, 5]: 1 occurrence + new Query(2, 8, 1), // Count of 3 in range [2, 8]: 2 occurrences + new Query(6, 9, 2) // Count of 3 in range [6, 9]: 1 occurrence + }; + + // Store original frequency queries for display + Query[] originalFreqQueries = new Query[freqQueries.length]; + for (int i = 0; i < freqQueries.length; i++) { + originalFreqQueries[i] = new Query(freqQueries[i].left, freqQueries[i].right, freqQueries[i].index); + } + + int[] freqResults = solveRangeFrequencyQueries(arr, freqQueries, 3); + + for (int i = 0; i < originalFreqQueries.length; i++) { + System.out.printf("Query %d: Count of 3 in range [%d, %d] = %d%n", i, originalFreqQueries[i].left, originalFreqQueries[i].right, freqResults[i]); + } + } +} diff --git a/src/main/java/com/thealgorithms/recursion/DiceThrower.java b/src/main/java/com/thealgorithms/recursion/DiceThrower.java new file mode 100644 index 000000000000..f46d82213aaa --- /dev/null +++ b/src/main/java/com/thealgorithms/recursion/DiceThrower.java @@ -0,0 +1,113 @@ +package com.thealgorithms.recursion; + +import java.util.ArrayList; +import java.util.List; + +/** + * DiceThrower - Generates all possible dice roll combinations that sum to a target + * + * This algorithm uses recursive backtracking to find all combinations of dice rolls + * (faces 1-6) that sum to a given target value. + * + * Example: If target = 4, possible combinations include: + * - "1111" (1+1+1+1 = 4) + * - "13" (1+3 = 4) + * - "22" (2+2 = 4) + * - "4" (4 = 4) + * + * @author BEASTSHRIRAM + * @see Backtracking Algorithm + */ +public final class DiceThrower { + + private DiceThrower() { + // Utility class + } + + /** + * Returns all possible dice roll combinations that sum to the target + * + * @param target the target sum to achieve with dice rolls + * @return list of all possible combinations as strings + */ + public static List getDiceCombinations(int target) { + if (target < 0) { + throw new IllegalArgumentException("Target must be non-negative"); + } + return generateCombinations("", target); + } + + /** + * Prints all possible dice roll combinations that sum to the target + * + * @param target the target sum to achieve with dice rolls + */ + public static void printDiceCombinations(int target) { + if (target < 0) { + throw new IllegalArgumentException("Target must be non-negative"); + } + printCombinations("", target); + } + + /** + * Recursive helper method to generate all combinations + * + * @param current the current combination being built + * @param remaining the remaining sum needed + * @return list of all combinations from this state + */ + private static List generateCombinations(String current, int remaining) { + List combinations = new ArrayList<>(); + + // Base case: if remaining sum is 0, we found a valid combination + if (remaining == 0) { + combinations.add(current); + return combinations; + } + + // Try all possible dice faces (1-6), but not more than remaining sum + for (int face = 1; face <= 6 && face <= remaining; face++) { + List subCombinations = generateCombinations(current + face, remaining - face); + combinations.addAll(subCombinations); + } + + return combinations; + } + + /** + * Recursive helper method to print all combinations + * + * @param current the current combination being built + * @param remaining the remaining sum needed + */ + private static void printCombinations(String current, int remaining) { + // Base case: if remaining sum is 0, we found a valid combination + if (remaining == 0) { + System.out.println(current); + return; + } + + // Try all possible dice faces (1-6), but not more than remaining sum + for (int face = 1; face <= 6 && face <= remaining; face++) { + printCombinations(current + face, remaining - face); + } + } + + /** + * Demo method to show usage + * + * @param args command line arguments + */ + public static void main(String[] args) { + int target = 4; + + System.out.println("All dice combinations that sum to " + target + ":"); + List combinations = getDiceCombinations(target); + + for (String combination : combinations) { + System.out.println(combination); + } + + System.out.println("\nTotal combinations: " + combinations.size()); + } +} diff --git a/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java b/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java new file mode 100644 index 000000000000..f4cb80f6a817 --- /dev/null +++ b/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java @@ -0,0 +1,178 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * Test class for MosAlgorithm + * + * @author BEASTSHRIRAM + */ +class MosAlgorithmTest { + + @Test + void testRangeSumQueriesBasic() { + int[] arr = {1, 3, 5, 2, 7}; + MosAlgorithm.Query[] queries = { + new MosAlgorithm.Query(0, 2, 0), // Sum of [1, 3, 5] = 9 + new MosAlgorithm.Query(1, 3, 1), // Sum of [3, 5, 2] = 10 + new MosAlgorithm.Query(2, 4, 2) // Sum of [5, 2, 7] = 14 + }; + + int[] expected = {9, 10, 14}; + int[] results = MosAlgorithm.solveRangeSumQueries(arr, queries); + + assertArrayEquals(expected, results); + } + + @Test + void testRangeSumQueriesSingleElement() { + int[] arr = {5, 10, 15, 20}; + MosAlgorithm.Query[] queries = { + new MosAlgorithm.Query(0, 0, 0), // Sum of [5] = 5 + new MosAlgorithm.Query(1, 1, 1), // Sum of [10] = 10 + new MosAlgorithm.Query(2, 2, 2), // Sum of [15] = 15 + new MosAlgorithm.Query(3, 3, 3) // Sum of [20] = 20 + }; + + int[] expected = {5, 10, 15, 20}; + int[] results = MosAlgorithm.solveRangeSumQueries(arr, queries); + + assertArrayEquals(expected, results); + } + + @Test + void testRangeSumQueriesFullArray() { + int[] arr = {1, 2, 3, 4, 5}; + MosAlgorithm.Query[] queries = { + new MosAlgorithm.Query(0, 4, 0) // Sum of entire array = 15 + }; + + int[] expected = {15}; + int[] results = MosAlgorithm.solveRangeSumQueries(arr, queries); + + assertArrayEquals(expected, results); + } + + @Test + void testRangeSumQueriesOverlapping() { + int[] arr = {2, 4, 6, 8, 10}; + MosAlgorithm.Query[] queries = { + new MosAlgorithm.Query(0, 2, 0), // Sum of [2, 4, 6] = 12 + new MosAlgorithm.Query(1, 3, 1), // Sum of [4, 6, 8] = 18 + new MosAlgorithm.Query(2, 4, 2) // Sum of [6, 8, 10] = 24 + }; + + int[] expected = {12, 18, 24}; + int[] results = MosAlgorithm.solveRangeSumQueries(arr, queries); + + assertArrayEquals(expected, results); + } + + @Test + void testRangeFrequencyQueriesBasic() { + int[] arr = {1, 2, 2, 1, 3, 2, 1}; + MosAlgorithm.Query[] queries = { + new MosAlgorithm.Query(0, 3, 0), // Count of 2 in [1, 2, 2, 1] = 2 + new MosAlgorithm.Query(1, 5, 1), // Count of 2 in [2, 2, 1, 3, 2] = 3 + new MosAlgorithm.Query(4, 6, 2) // Count of 2 in [3, 2, 1] = 1 + }; + + int[] expected = {2, 3, 1}; + int[] results = MosAlgorithm.solveRangeFrequencyQueries(arr, queries, 2); + + assertArrayEquals(expected, results); + } + + @Test + void testRangeFrequencyQueriesNoMatch() { + int[] arr = {1, 3, 5, 7, 9}; + MosAlgorithm.Query[] queries = { + new MosAlgorithm.Query(0, 2, 0), // Count of 2 in [1, 3, 5] = 0 + new MosAlgorithm.Query(1, 4, 1) // Count of 2 in [3, 5, 7, 9] = 0 + }; + + int[] expected = {0, 0}; + int[] results = MosAlgorithm.solveRangeFrequencyQueries(arr, queries, 2); + + assertArrayEquals(expected, results); + } + + @Test + void testRangeFrequencyQueriesAllMatch() { + int[] arr = {5, 5, 5, 5, 5}; + MosAlgorithm.Query[] queries = { + new MosAlgorithm.Query(0, 2, 0), // Count of 5 in [5, 5, 5] = 3 + new MosAlgorithm.Query(1, 3, 1), // Count of 5 in [5, 5, 5] = 3 + new MosAlgorithm.Query(0, 4, 2) // Count of 5 in [5, 5, 5, 5, 5] = 5 + }; + + int[] expected = {3, 3, 5}; + int[] results = MosAlgorithm.solveRangeFrequencyQueries(arr, queries, 5); + + assertArrayEquals(expected, results); + } + + @Test + void testEmptyArray() { + int[] arr = {}; + MosAlgorithm.Query[] queries = {}; + + int[] expected = {}; + int[] results = MosAlgorithm.solveRangeSumQueries(arr, queries); + + assertArrayEquals(expected, results); + } + + @Test + void testNullInputs() { + int[] results1 = MosAlgorithm.solveRangeSumQueries(null, null); + assertArrayEquals(new int[0], results1); + + int[] results2 = MosAlgorithm.solveRangeFrequencyQueries(null, null, 1); + assertArrayEquals(new int[0], results2); + } + + @Test + void testQueryStructure() { + MosAlgorithm.Query query = new MosAlgorithm.Query(1, 5, 0); + + assertEquals(1, query.left); + assertEquals(5, query.right); + assertEquals(0, query.index); + assertEquals(0, query.result); // Default value + } + + @Test + void testLargerArray() { + int[] arr = {1, 4, 2, 8, 5, 7, 3, 6, 9, 10}; + MosAlgorithm.Query[] queries = { + new MosAlgorithm.Query(0, 4, 0), // Sum of [1, 4, 2, 8, 5] = 20 + new MosAlgorithm.Query(2, 7, 1), // Sum of [2, 8, 5, 7, 3, 6] = 31 + new MosAlgorithm.Query(5, 9, 2), // Sum of [7, 3, 6, 9, 10] = 35 + new MosAlgorithm.Query(1, 8, 3) // Sum of [4, 2, 8, 5, 7, 3, 6, 9] = 44 + }; + + int[] expected = {20, 31, 35, 44}; + int[] results = MosAlgorithm.solveRangeSumQueries(arr, queries); + + assertArrayEquals(expected, results); + } + + @Test + void testRangeFrequencyWithDuplicates() { + int[] arr = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3}; + MosAlgorithm.Query[] queries = { + new MosAlgorithm.Query(0, 5, 0), // Count of 1 in [3, 1, 4, 1, 5, 9] = 2 + new MosAlgorithm.Query(3, 9, 1), // Count of 1 in [1, 5, 9, 2, 6, 5, 3] = 1 + new MosAlgorithm.Query(0, 9, 2) // Count of 1 in entire array = 2 + }; + + int[] expected = {2, 1, 2}; + int[] results = MosAlgorithm.solveRangeFrequencyQueries(arr, queries, 1); + + assertArrayEquals(expected, results); + } +} diff --git a/src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java b/src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java new file mode 100644 index 000000000000..b89eab7824cf --- /dev/null +++ b/src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java @@ -0,0 +1,127 @@ +package com.thealgorithms.recursion; + +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.List; +import org.junit.jupiter.api.Test; + +/** + * Test class for DiceThrower + * + * @author BEASTSHRIRAM + */ +class DiceThrowerTest { + + @Test + void testTargetZero() { + List result = DiceThrower.getDiceCombinations(0); + assertEquals(1, result.size()); + assertEquals("", result.get(0)); + } + + @Test + void testTargetOne() { + List result = DiceThrower.getDiceCombinations(1); + assertEquals(1, result.size()); + assertEquals("1", result.get(0)); + } + + @Test + void testTargetTwo() { + List result = DiceThrower.getDiceCombinations(2); + assertEquals(2, result.size()); + assertTrue(result.contains("11")); + assertTrue(result.contains("2")); + } + + @Test + void testTargetThree() { + List result = DiceThrower.getDiceCombinations(3); + assertEquals(4, result.size()); + assertTrue(result.contains("111")); + assertTrue(result.contains("12")); + assertTrue(result.contains("21")); + assertTrue(result.contains("3")); + } + + @Test + void testTargetFour() { + List result = DiceThrower.getDiceCombinations(4); + assertEquals(8, result.size()); + assertTrue(result.contains("1111")); + assertTrue(result.contains("112")); + assertTrue(result.contains("121")); + assertTrue(result.contains("13")); + assertTrue(result.contains("211")); + assertTrue(result.contains("22")); + assertTrue(result.contains("31")); + assertTrue(result.contains("4")); + } + + @Test + void testTargetSix() { + List result = DiceThrower.getDiceCombinations(6); + assertEquals(32, result.size()); + assertTrue(result.contains("6")); + assertTrue(result.contains("33")); + assertTrue(result.contains("222")); + assertTrue(result.contains("111111")); + } + + @Test + void testTargetSeven() { + List result = DiceThrower.getDiceCombinations(7); + // Should include combinations like 61, 52, 43, 331, 322, 2221, etc. + assertTrue(result.size() > 0); + assertTrue(result.contains("61")); + assertTrue(result.contains("16")); + assertTrue(result.contains("52")); + assertTrue(result.contains("43")); + } + + @Test + void testLargerTarget() { + List result = DiceThrower.getDiceCombinations(10); + assertTrue(result.size() > 0); + // All results should sum to 10 + for (String combination : result) { + int sum = 0; + for (char c : combination.toCharArray()) { + sum += Character.getNumericValue(c); + } + assertEquals(10, sum); + } + } + + @Test + void testNegativeTarget() { + assertThrows(IllegalArgumentException.class, () -> { DiceThrower.getDiceCombinations(-1); }); + } + + @Test + void testNegativeTargetPrint() { + assertThrows(IllegalArgumentException.class, () -> { DiceThrower.printDiceCombinations(-1); }); + } + + @Test + void testAllCombinationsValid() { + List result = DiceThrower.getDiceCombinations(5); + + for (String combination : result) { + // Check that each character is a valid dice face (1-6) + for (char c : combination.toCharArray()) { + int face = Character.getNumericValue(c); + assertTrue(face >= 1 && face <= 6, "Invalid dice face: " + face); + } + + // Check that the sum equals the target + int sum = 0; + for (char c : combination.toCharArray()) { + sum += Character.getNumericValue(c); + } + assertEquals(5, sum, "Combination " + combination + " does not sum to 5"); + } + } +} From 4c421fa058a28524d6c324f17266c99439f98e59 Mon Sep 17 00:00:00 2001 From: shriramthebeast Date: Thu, 2 Oct 2025 19:19:33 +0530 Subject: [PATCH 05/10] Fixed checkstyle violation --- src/main/java/com/thealgorithms/others/MosAlgorithm.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/others/MosAlgorithm.java b/src/main/java/com/thealgorithms/others/MosAlgorithm.java index 847c4e9b1bf9..0a185a9a4b1f 100644 --- a/src/main/java/com/thealgorithms/others/MosAlgorithm.java +++ b/src/main/java/com/thealgorithms/others/MosAlgorithm.java @@ -183,7 +183,7 @@ public static int[] solveRangeFrequencyQueries(int[] arr, Query[] queries, int t private static class MoComparator implements Comparator { private final int blockSize; - public MoComparator(int blockSize) { + MoComparator(int blockSize) { this.blockSize = blockSize; } From 857b074e8df85cda1f7af29950d99868b88b3049 Mon Sep 17 00:00:00 2001 From: shriramthebeast Date: Thu, 2 Oct 2025 19:24:11 +0530 Subject: [PATCH 06/10] Fixed SpotBugs issue --- src/main/java/com/thealgorithms/others/MosAlgorithm.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/others/MosAlgorithm.java b/src/main/java/com/thealgorithms/others/MosAlgorithm.java index 0a185a9a4b1f..2d2778339a7a 100644 --- a/src/main/java/com/thealgorithms/others/MosAlgorithm.java +++ b/src/main/java/com/thealgorithms/others/MosAlgorithm.java @@ -198,7 +198,7 @@ public int compare(Query a, Query b) { // For odd blocks, sort right in ascending order // For even blocks, sort right in descending order (optimization) - if (blockA % 2 == 1) { + if ((blockA & 1) == 1) { return Integer.compare(a.right, b.right); } else { return Integer.compare(b.right, a.right); From f8f16e79a1e5ec699532016fb8439365d4b001c8 Mon Sep 17 00:00:00 2001 From: shriramthebeast Date: Thu, 2 Oct 2025 19:29:22 +0530 Subject: [PATCH 07/10] Added in PMD exclusions --- pmd-exclude.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pmd-exclude.properties b/pmd-exclude.properties index 4c0ed625d884..a3c95b12fa4b 100644 --- a/pmd-exclude.properties +++ b/pmd-exclude.properties @@ -88,12 +88,14 @@ com.thealgorithms.others.LinearCongruentialGenerator=UselessMainMethod com.thealgorithms.others.Luhn=UnnecessaryFullyQualifiedName,UselessMainMethod com.thealgorithms.others.Mandelbrot=UselessMainMethod,UselessParentheses com.thealgorithms.others.MiniMaxAlgorithm=UselessMainMethod,UselessParentheses +com.thealgorithms.others.MosAlgorithm=UselessMainMethod com.thealgorithms.others.PageRank=UselessMainMethod,UselessParentheses com.thealgorithms.others.PerlinNoise=UselessMainMethod,UselessParentheses com.thealgorithms.others.QueueUsingTwoStacks=UselessParentheses com.thealgorithms.others.Trieac=UselessMainMethod,UselessParentheses com.thealgorithms.others.Verhoeff=UnnecessaryFullyQualifiedName,UselessMainMethod com.thealgorithms.puzzlesandgames.Sudoku=UselessMainMethod +com.thealgorithms.recursion.DiceThrower=UselessMainMethod com.thealgorithms.searches.HowManyTimesRotated=UselessMainMethod com.thealgorithms.searches.InterpolationSearch=UselessParentheses com.thealgorithms.searches.KMPSearch=UselessParentheses From 68775a168d8993bf8396805a61e324b33850e10a Mon Sep 17 00:00:00 2001 From: shriramthebeast Date: Sun, 5 Oct 2025 14:28:34 +0530 Subject: [PATCH 08/10] Improved test coverage for better Codecov scores. --- .../others/MosAlgorithmTest.java | 24 +++++ .../recursion/DiceThrowerTest.java | 96 +++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java b/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java index f4cb80f6a817..3ed3d57d8894 100644 --- a/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java +++ b/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java @@ -2,7 +2,10 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import org.junit.jupiter.api.Test; /** @@ -175,4 +178,25 @@ void testRangeFrequencyWithDuplicates() { assertArrayEquals(expected, results); } + + @Test + void testMainMethod() { + // Capture System.out + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PrintStream originalOut = System.out; + System.setOut(new PrintStream(outputStream)); + + try { + // Test main method + MosAlgorithm.main(new String[]{}); + String output = outputStream.toString(); + + // Verify expected output contains demonstration + assertTrue(output.contains("Range Sum Queries Results:")); + assertTrue(output.contains("Range Frequency Queries Results:")); + assertTrue(output.contains("Count of 2 in ranges:")); + } finally { + System.setOut(originalOut); + } + } } diff --git a/src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java b/src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java index b89eab7824cf..0febe41fcbf8 100644 --- a/src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java +++ b/src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java @@ -4,6 +4,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import java.util.List; import org.junit.jupiter.api.Test; @@ -124,4 +126,98 @@ void testAllCombinationsValid() { assertEquals(5, sum, "Combination " + combination + " does not sum to 5"); } } + + @Test + void testPrintDiceCombinations() { + // Capture System.out + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PrintStream originalOut = System.out; + System.setOut(new PrintStream(outputStream)); + + try { + // Test printing combinations for target 3 + DiceThrower.printDiceCombinations(3); + String output = outputStream.toString(); + + // Verify all expected combinations are printed + assertTrue(output.contains("111")); + assertTrue(output.contains("12")); + assertTrue(output.contains("21")); + assertTrue(output.contains("3")); + + // Count number of lines (combinations) + String[] lines = output.trim().split("\n"); + assertEquals(4, lines.length); + } finally { + // Restore System.out + System.setOut(originalOut); + } + } + + @Test + void testPrintDiceCombinationsZero() { + // Capture System.out + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PrintStream originalOut = System.out; + System.setOut(new PrintStream(outputStream)); + + try { + DiceThrower.printDiceCombinations(0); + String output = outputStream.toString(); + + // Should print empty string (one line) + assertEquals("", output.trim()); + } finally { + System.setOut(originalOut); + } + } + + @Test + void testMainMethod() { + // Capture System.out + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PrintStream originalOut = System.out; + System.setOut(new PrintStream(outputStream)); + + try { + // Test main method + DiceThrower.main(new String[]{}); + String output = outputStream.toString(); + + // Verify expected output contains header and combinations + assertTrue(output.contains("All dice combinations that sum to 4:")); + assertTrue(output.contains("Total combinations: 8")); + assertTrue(output.contains("1111")); + assertTrue(output.contains("22")); + assertTrue(output.contains("4")); + } finally { + System.setOut(originalOut); + } + } + + @Test + void testEdgeCaseTargetFive() { + List result = DiceThrower.getDiceCombinations(5); + assertEquals(16, result.size()); + + // Test specific combinations exist + assertTrue(result.contains("11111")); + assertTrue(result.contains("1112")); + assertTrue(result.contains("122")); + assertTrue(result.contains("14")); + assertTrue(result.contains("23")); + assertTrue(result.contains("5")); + } + + @Test + void testTargetGreaterThanSix() { + List result = DiceThrower.getDiceCombinations(8); + assertTrue(result.size() > 0); + + // Verify some expected combinations + assertTrue(result.contains("62")); + assertTrue(result.contains("53")); + assertTrue(result.contains("44")); + assertTrue(result.contains("2222")); + } } From df609d636fdcd8bb6a36ce78c1cb69b2def5397a Mon Sep 17 00:00:00 2001 From: shriramthebeast Date: Sun, 5 Oct 2025 14:31:36 +0530 Subject: [PATCH 09/10] Fixed clang-format issues in test files --- .../com/thealgorithms/others/MosAlgorithmTest.java | 4 ++-- .../thealgorithms/recursion/DiceThrowerTest.java | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java b/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java index 3ed3d57d8894..03e85430ca11 100644 --- a/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java +++ b/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java @@ -188,9 +188,9 @@ void testMainMethod() { try { // Test main method - MosAlgorithm.main(new String[]{}); + MosAlgorithm.main(new String[] {}); String output = outputStream.toString(); - + // Verify expected output contains demonstration assertTrue(output.contains("Range Sum Queries Results:")); assertTrue(output.contains("Range Frequency Queries Results:")); diff --git a/src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java b/src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java index 0febe41fcbf8..0804e9bfff25 100644 --- a/src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java +++ b/src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java @@ -138,13 +138,13 @@ void testPrintDiceCombinations() { // Test printing combinations for target 3 DiceThrower.printDiceCombinations(3); String output = outputStream.toString(); - + // Verify all expected combinations are printed assertTrue(output.contains("111")); assertTrue(output.contains("12")); assertTrue(output.contains("21")); assertTrue(output.contains("3")); - + // Count number of lines (combinations) String[] lines = output.trim().split("\n"); assertEquals(4, lines.length); @@ -164,7 +164,7 @@ void testPrintDiceCombinationsZero() { try { DiceThrower.printDiceCombinations(0); String output = outputStream.toString(); - + // Should print empty string (one line) assertEquals("", output.trim()); } finally { @@ -181,9 +181,9 @@ void testMainMethod() { try { // Test main method - DiceThrower.main(new String[]{}); + DiceThrower.main(new String[] {}); String output = outputStream.toString(); - + // Verify expected output contains header and combinations assertTrue(output.contains("All dice combinations that sum to 4:")); assertTrue(output.contains("Total combinations: 8")); @@ -199,7 +199,7 @@ void testMainMethod() { void testEdgeCaseTargetFive() { List result = DiceThrower.getDiceCombinations(5); assertEquals(16, result.size()); - + // Test specific combinations exist assertTrue(result.contains("11111")); assertTrue(result.contains("1112")); @@ -213,7 +213,7 @@ void testEdgeCaseTargetFive() { void testTargetGreaterThanSix() { List result = DiceThrower.getDiceCombinations(8); assertTrue(result.size() > 0); - + // Verify some expected combinations assertTrue(result.contains("62")); assertTrue(result.contains("53")); From c7a040605463866c77e323ad950425001db49794 Mon Sep 17 00:00:00 2001 From: shriramthebeast Date: Sun, 5 Oct 2025 14:40:42 +0530 Subject: [PATCH 10/10] Add Mo's Algorithm and DiceThrower algorithms with comprehensive tests * Fixed PartitionProblem.java documentation comment placement --- pom.xml | 3 +-- .../dynamicprogramming/PartitionProblem.java | 9 ++++----- .../java/com/thealgorithms/others/MosAlgorithmTest.java | 6 +++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 2122e6660da3..9049b21e3ba6 100644 --- a/pom.xml +++ b/pom.xml @@ -71,8 +71,7 @@ maven-compiler-plugin 3.14.1 - 21 - 21 + 21 -Xlint:all -Xlint:-auxiliaryclass diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java b/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java index 49c4a0a3a008..8f69d1148ed5 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java @@ -1,3 +1,7 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.Arrays; + /** * @author Md Asif Joardar * @@ -13,11 +17,6 @@ * * The time complexity of the solution is O(n × sum) and requires O(n × sum) space */ - -package com.thealgorithms.dynamicprogramming; - -import java.util.Arrays; - public final class PartitionProblem { private PartitionProblem() { } diff --git a/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java b/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java index 03e85430ca11..ac931eb0a2b9 100644 --- a/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java +++ b/src/test/java/com/thealgorithms/others/MosAlgorithmTest.java @@ -192,9 +192,9 @@ void testMainMethod() { String output = outputStream.toString(); // Verify expected output contains demonstration - assertTrue(output.contains("Range Sum Queries Results:")); - assertTrue(output.contains("Range Frequency Queries Results:")); - assertTrue(output.contains("Count of 2 in ranges:")); + assertTrue(output.contains("Range Sum Queries:")); + assertTrue(output.contains("Range Frequency Queries (count of value 3):")); + assertTrue(output.contains("Array: [1, 3, 5, 2, 7, 6, 3, 1, 4, 8]")); } finally { System.setOut(originalOut); }