From 5bb54977fe63107c22116215023cb18fc5500113 Mon Sep 17 00:00:00 2001
From: Manan Solanki <76104205+Manan-09@users.noreply.github.com>
Date: Thu, 14 Sep 2023 23:15:16 +0530
Subject: [PATCH 0001/1151] #4369 Enhance UniquePaths (#4373)
* Enhance UnquiePaths DP problem solution
* Update testcases
* Linter issue resolved
* Code review comments
* Code review comments
* Code review comments
* Code review comments
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../dynamicprogramming/UniquePaths.java | 80 +++++++++++--------
.../dynamicprogramming/UniquePathsTests.java | 58 ++++++++++++++
.../others/UniquePathsTests.java | 49 ------------
3 files changed, 104 insertions(+), 83 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java
delete mode 100644 src/test/java/com/thealgorithms/others/UniquePathsTests.java
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java b/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java
index 2cfb8ef25058..c48bdea2dc8d 100644
--- a/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java
@@ -1,59 +1,71 @@
/**
- * Author : Siddhant Swarup Mallick
- * Github : https://github.com/siddhant2002
- */
-
-/**
+ * Author: Siddhant Swarup Mallick
+ * Github: https://github.com/siddhant2002
+ *
+ * Problem Description:
* A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).
* The robot can only move either down or right at any point in time.
- * The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram
- * below). How many possible unique paths are there?
+ * The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).
+ * How many possible unique paths are there?
+ *
+ * Program Description:
+ * This program calculates the number of unique paths possible for a robot to reach the bottom-right corner
+ * of an m x n grid using dynamic programming.
*/
-/** Program description - To find the number of unique paths possible */
-
package com.thealgorithms.dynamicprogramming;
-import java.util.*;
+import java.util.Arrays;
-public class UniquePaths {
+public final class UniquePaths {
- public static boolean uniquePaths(int m, int n, int ans) {
- int[] dp = new int[n];
- Arrays.fill(dp, 1);
+ private UniquePaths(){};
+
+ /**
+ * Calculates the number of unique paths using a 1D dynamic programming array.
+ * Time complexity O(n*m)
+ * Space complexity O(min(n,m))
+ *
+ * @param m The number of rows in the grid.
+ * @param n The number of columns in the grid.
+ * @return The number of unique paths.
+ */
+ public static int uniquePaths(final int m, final int n) {
+ if (m > n) {
+ return uniquePaths(n, m); // Recursive call to handle n > m cases
+ }
+ int[] dp = new int[n]; // Create a 1D array to store unique paths for each column
+ Arrays.fill(dp, 1); // Initialize all values to 1 (one way to reach each cell)
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
- dp[j] += dp[j - 1];
+ dp[j] = Math.addExact(dp[j], dp[j - 1]); // Update the number of unique paths for each cell
}
}
- return dp[n - 1] == ans;
- // return true if predicted answer matches with expected answer
+ return dp[n - 1]; // The result is stored in the last column of the array
}
- // The above method runs in O(n) time
- public static boolean uniquePaths2(int m, int n, int ans) {
- int[][] dp = new int[m][n];
+ /**
+ * Calculates the number of unique paths using a 2D dynamic programming array.
+ * Time complexity O(n*m)
+ * Space complexity O(n*m)
+ *
+ * @param m The number of rows in the grid.
+ * @param n The number of columns in the grid.
+ * @return The number of unique paths.
+ */
+ public static int uniquePaths2(final int m, final int n) {
+ int[][] dp = new int[m][n]; // Create a 2D array to store unique paths for each cell
for (int i = 0; i < m; i++) {
- dp[i][0] = 1;
+ dp[i][0] = 1; // Initialize the first column to 1 (one way to reach each cell)
}
for (int j = 0; j < n; j++) {
- dp[0][j] = 1;
+ dp[0][j] = 1; // Initialize the first row to 1 (one way to reach each cell)
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
- dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
+ dp[i][j] = Math.addExact(dp[i - 1][j], dp[i][j - 1]); // Update the number of unique paths for each cell
}
}
- return dp[m - 1][n - 1] == ans;
- // return true if predicted answer matches with expected answer
+ return dp[m - 1][n - 1]; // The result is stored in the bottom-right cell of the array
}
- // The above mthod takes O(m*n) time
}
-/**
- * OUTPUT :
- * Input - m = 3, n = 7
- * Output: it returns either true if expected answer matches with the predicted answer else it
- * returns false 1st approach Time Complexity : O(n) Auxiliary Space Complexity : O(n) Input - m =
- * 3, n = 7 Output: it returns either true if expected answer matches with the predicted answer else
- * it returns false 2nd approach Time Complexity : O(m*n) Auxiliary Space Complexity : O(m*n)
- */
diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java b/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java
new file mode 100644
index 000000000000..f6a86e72ad9c
--- /dev/null
+++ b/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java
@@ -0,0 +1,58 @@
+package com.thealgorithms.dynamicprogramming;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class UniquePathsTests {
+
+ @Test
+ public void testUniquePaths_3x3() {
+ assertEquals(6, UniquePaths.uniquePaths(3, 3));
+ }
+
+ @Test
+ public void testUniquePaths_1x1() {
+ assertEquals(1, UniquePaths.uniquePaths(1, 1));
+ }
+
+ @Test
+ public void testUniquePaths_3x7() {
+ assertEquals(28, UniquePaths.uniquePaths(3, 7));
+ }
+
+ @Test
+ public void testUniquePaths_7x3() {
+ assertEquals(28, UniquePaths.uniquePaths(7, 3));
+ }
+
+ @Test
+ public void testUniquePaths_100x100() {
+ assertThrows(ArithmeticException.class, () -> UniquePaths.uniquePaths(100, 100));
+ }
+
+ @Test
+ public void testUniquePaths2_3x3() {
+ assertEquals(6, UniquePaths.uniquePaths2(3, 3));
+ }
+
+ @Test
+ public void testUniquePaths2_1x1() {
+ assertEquals(1, UniquePaths.uniquePaths2(1, 1));
+ }
+
+ @Test
+ public void testUniquePaths2_3x7() {
+ assertEquals(28, UniquePaths.uniquePaths2(3, 7));
+ }
+
+ @Test
+ public void testUniquePaths2_7x3() {
+ assertEquals(28, UniquePaths.uniquePaths2(7, 3));
+ }
+
+ @Test
+ public void testUniquePaths2_100x100() {
+ assertThrows(ArithmeticException.class, () -> UniquePaths.uniquePaths2(100, 100));
+ }
+}
diff --git a/src/test/java/com/thealgorithms/others/UniquePathsTests.java b/src/test/java/com/thealgorithms/others/UniquePathsTests.java
deleted file mode 100644
index 42a11c441dc7..000000000000
--- a/src/test/java/com/thealgorithms/others/UniquePathsTests.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.thealgorithms.others;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import com.thealgorithms.dynamicprogramming.UniquePaths;
-import org.junit.jupiter.api.Test;
-
-public class UniquePathsTests {
-
- @Test
- void testForOneElement() {
- assertTrue(UniquePaths.uniquePaths(3, 7, 28));
- }
-
- @Test
- void testForTwoElements() {
- assertTrue(UniquePaths.uniquePaths(3, 2, 3));
- }
-
- @Test
- void testForThreeElements() {
- assertTrue(UniquePaths.uniquePaths(3, 3, 6));
- }
-
- @Test
- void testForFourElements() {
- assertTrue(UniquePaths.uniquePaths(4, 6, 56));
- }
-
- @Test
- void testForFiveElements() {
- assertTrue(UniquePaths.uniquePaths2(3, 5, 15));
- }
-
- @Test
- void testForSixElements() {
- assertTrue(UniquePaths.uniquePaths2(6, 2, 6));
- }
-
- @Test
- void testForSevenElements() {
- assertTrue(UniquePaths.uniquePaths2(5, 9, 495));
- }
-
- @Test
- void testForEightElements() {
- assertTrue(UniquePaths.uniquePaths2(4, 8, 120));
- }
-}
From 58c21c57561a577c9e398aafcc104d1bf495e7bf Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Sat, 16 Sep 2023 20:57:03 +0200
Subject: [PATCH 0002/1151] refactor: simplify `ParseInteger` (#4376)
---
.../com/thealgorithms/maths/ParseInteger.java | 43 +++++++++++++------
.../thealgorithms/maths/ParseIntegerTest.java | 7 +++
2 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/ParseInteger.java b/src/main/java/com/thealgorithms/maths/ParseInteger.java
index a396a7b0ddfe..cdca9f815c4d 100644
--- a/src/main/java/com/thealgorithms/maths/ParseInteger.java
+++ b/src/main/java/com/thealgorithms/maths/ParseInteger.java
@@ -1,6 +1,28 @@
package com.thealgorithms.maths;
-public class ParseInteger {
+public final class ParseInteger {
+ private ParseInteger() {
+ }
+
+ private static void checkInput(final String s) {
+ if (s == null) {
+ throw new NumberFormatException("Input parameter must not be null!");
+ }
+ if (s.isEmpty()) {
+ throw new NumberFormatException("Input parameter must not be empty!");
+ }
+ }
+
+ private static void checkDigitAt(final String s, final int pos) {
+ if (!Character.isDigit(s.charAt(pos))) {
+ throw new NumberFormatException("Input parameter of incorrect format: " + s);
+ }
+ }
+
+ private static int digitToInt(final char digit) {
+ return digit - '0';
+ }
+
/**
* Parse a string to integer
*
@@ -9,18 +31,15 @@ public class ParseInteger {
* @throws NumberFormatException if the {@code string} does not contain a
* parsable integer.
*/
- public static int parseInt(String s) {
- if (s == null || s.length() == 0) {
- throw new NumberFormatException("Input parameter must not be null!");
- }
- boolean isNegative = s.charAt(0) == '-';
- boolean isPositive = s.charAt(0) == '+';
+ public static int parseInt(final String s) {
+ checkInput(s);
+
+ final boolean isNegative = s.charAt(0) == '-';
+ final boolean isPositive = s.charAt(0) == '+';
int number = 0;
- for (int i = isNegative ? 1 : isPositive ? 1 : 0, length = s.length(); i < length; ++i) {
- if (!Character.isDigit(s.charAt(i))) {
- throw new NumberFormatException("Input parameter of incorrect format: " + s);
- }
- number = number * 10 + s.charAt(i) - '0';
+ for (int i = isNegative || isPositive ? 1 : 0, length = s.length(); i < length; ++i) {
+ checkDigitAt(s, i);
+ number = number * 10 + digitToInt(s.charAt(i));
}
return isNegative ? -number : number;
}
diff --git a/src/test/java/com/thealgorithms/maths/ParseIntegerTest.java b/src/test/java/com/thealgorithms/maths/ParseIntegerTest.java
index dc5bf37f0382..7649e21eb231 100644
--- a/src/test/java/com/thealgorithms/maths/ParseIntegerTest.java
+++ b/src/test/java/com/thealgorithms/maths/ParseIntegerTest.java
@@ -8,6 +8,7 @@
*/
public class ParseIntegerTest {
private static final String NULL_PARAMETER_MESSAGE = "Input parameter must not be null!";
+ private static final String EMPTY_PARAMETER_MESSAGE = "Input parameter must not be empty!";
private static final String INCORRECT_FORMAT_MESSAGE = "Input parameter of incorrect format";
@Test
@@ -16,6 +17,12 @@ public void testNullInput() {
Assertions.assertEquals(exception.getMessage(), NULL_PARAMETER_MESSAGE);
}
+ @Test
+ public void testEmptyInput() {
+ IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class, () -> ParseInteger.parseInt(""));
+ Assertions.assertEquals(exception.getMessage(), EMPTY_PARAMETER_MESSAGE);
+ }
+
@Test
public void testInputOfIncorrectFormat() {
IllegalArgumentException exception = Assertions.assertThrows(NumberFormatException.class, () -> ParseInteger.parseInt("+0a123"));
From a1844840fd99bcc38293b5ebfb705357152e7fbc Mon Sep 17 00:00:00 2001
From: Andrii Siriak
Date: Sun, 17 Sep 2023 23:43:55 +0300
Subject: [PATCH 0003/1151] Add a note about leetcode to CONTRIBUTING.md
---
CONTRIBUTING.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 23ee1bb07a97..dcc86c50360d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,5 +1,7 @@
## How to contribute?
+NOTE: *We DO NOT add leetcode problems. They are just applications of basic principles that can be found in other algorithms included in the repository.*
+
### Did you find a bug?
**Ensure the bug was not already reported** by searching on GitHub under [Project Issues](https://github.com/TheAlgorithms/Java/issues).
From 26c2465328f81379047237b4bf54f134a73a7fd1 Mon Sep 17 00:00:00 2001
From: Subhradeep Bera <124783808+beradeep@users.noreply.github.com>
Date: Tue, 19 Sep 2023 00:57:36 +0530
Subject: [PATCH 0004/1151] Moved StackPostfixNotation.java from the Others
section to the Stack section (#4372)
* Moved StackPostfixNotation.java from the Others section to the Stack section
* Put all stack related algo in a separate stack directory in the algorithms directory. The stack directory under data-structures now only contains various implementations of the stack data structure.
* formatted files
---
.../stacks/BalancedBrackets.java | 2 +-
.../stacks/CalculateMaxOfMin.java | 2 +-
.../stacks/DecimalToAnyUsingStack.java | 2 +-
.../stacks/DuplicateBrackets.java | 2 +-
.../stacks/InfixToPostfix.java | 2 +-
.../stacks/LargestRectangle.java | 2 +-
.../stacks/MaximumMinimumWindow.java | 2 +-
.../stacks/NextGraterElement.java | 2 +-
.../stacks/NextSmallerElement.java | 2 +-
.../stacks/PostfixToInfix.java | 2 +-
.../StackPostfixNotation.java | 2 +-
.../CalculateMaxOfMinTest.java | 17 ++++++++---------
.../StackPostfixNotationTest.java | 5 ++---
13 files changed, 21 insertions(+), 23 deletions(-)
rename src/main/java/com/thealgorithms/{datastructures => }/stacks/BalancedBrackets.java (98%)
rename src/main/java/com/thealgorithms/{datastructures => }/stacks/CalculateMaxOfMin.java (95%)
rename src/main/java/com/thealgorithms/{datastructures => }/stacks/DecimalToAnyUsingStack.java (96%)
rename src/main/java/com/thealgorithms/{datastructures => }/stacks/DuplicateBrackets.java (96%)
rename src/main/java/com/thealgorithms/{datastructures => }/stacks/InfixToPostfix.java (97%)
rename src/main/java/com/thealgorithms/{datastructures => }/stacks/LargestRectangle.java (95%)
rename src/main/java/com/thealgorithms/{datastructures => }/stacks/MaximumMinimumWindow.java (98%)
rename src/main/java/com/thealgorithms/{datastructures => }/stacks/NextGraterElement.java (97%)
rename src/main/java/com/thealgorithms/{datastructures => }/stacks/NextSmallerElement.java (97%)
rename src/main/java/com/thealgorithms/{datastructures => }/stacks/PostfixToInfix.java (98%)
rename src/main/java/com/thealgorithms/{others => stacks}/StackPostfixNotation.java (98%)
rename src/test/java/com/thealgorithms/{others => stacks}/CalculateMaxOfMinTest.java (79%)
rename src/test/java/com/thealgorithms/{others => stacks}/StackPostfixNotationTest.java (90%)
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/BalancedBrackets.java b/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java
similarity index 98%
rename from src/main/java/com/thealgorithms/datastructures/stacks/BalancedBrackets.java
rename to src/main/java/com/thealgorithms/stacks/BalancedBrackets.java
index d80502d88e22..a73697a7df21 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/BalancedBrackets.java
+++ b/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java
@@ -1,4 +1,4 @@
-package com.thealgorithms.datastructures.stacks;
+package com.thealgorithms.stacks;
import java.util.Stack;
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/CalculateMaxOfMin.java b/src/main/java/com/thealgorithms/stacks/CalculateMaxOfMin.java
similarity index 95%
rename from src/main/java/com/thealgorithms/datastructures/stacks/CalculateMaxOfMin.java
rename to src/main/java/com/thealgorithms/stacks/CalculateMaxOfMin.java
index df7279bb217e..399b9efdc49b 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/CalculateMaxOfMin.java
+++ b/src/main/java/com/thealgorithms/stacks/CalculateMaxOfMin.java
@@ -7,7 +7,7 @@
* Program description - Given an integer array. The task is to find the maximum of the minimum of
* the array
*/
-package com.thealgorithms.datastructures.stacks;
+package com.thealgorithms.stacks;
import java.util.*;
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/DecimalToAnyUsingStack.java b/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java
similarity index 96%
rename from src/main/java/com/thealgorithms/datastructures/stacks/DecimalToAnyUsingStack.java
rename to src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java
index ec6c8414d585..0a206a8ba1e9 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/DecimalToAnyUsingStack.java
+++ b/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java
@@ -1,4 +1,4 @@
-package com.thealgorithms.datastructures.stacks;
+package com.thealgorithms.stacks;
import java.util.Stack;
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/DuplicateBrackets.java b/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java
similarity index 96%
rename from src/main/java/com/thealgorithms/datastructures/stacks/DuplicateBrackets.java
rename to src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java
index fb976360c9f5..7daf2e060e22 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/DuplicateBrackets.java
+++ b/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java
@@ -1,4 +1,4 @@
-package com.thealgorithms.datastructures.stacks;
+package com.thealgorithms.stacks;
// 1. You are given a string exp representing an expression.
// 2. Assume that the expression is balanced i.e. the opening and closing brackets match with each
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/InfixToPostfix.java b/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java
similarity index 97%
rename from src/main/java/com/thealgorithms/datastructures/stacks/InfixToPostfix.java
rename to src/main/java/com/thealgorithms/stacks/InfixToPostfix.java
index b009223330f0..2cafdc940650 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/InfixToPostfix.java
+++ b/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java
@@ -1,4 +1,4 @@
-package com.thealgorithms.datastructures.stacks;
+package com.thealgorithms.stacks;
import java.util.Stack;
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/LargestRectangle.java b/src/main/java/com/thealgorithms/stacks/LargestRectangle.java
similarity index 95%
rename from src/main/java/com/thealgorithms/datastructures/stacks/LargestRectangle.java
rename to src/main/java/com/thealgorithms/stacks/LargestRectangle.java
index f076d5d6a97e..63f1d0b4f30d 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/LargestRectangle.java
+++ b/src/main/java/com/thealgorithms/stacks/LargestRectangle.java
@@ -1,4 +1,4 @@
-package com.thealgorithms.datastructures.stacks;
+package com.thealgorithms.stacks;
import java.util.Stack;
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/MaximumMinimumWindow.java b/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java
similarity index 98%
rename from src/main/java/com/thealgorithms/datastructures/stacks/MaximumMinimumWindow.java
rename to src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java
index 88228000e904..5eb895d945e5 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/MaximumMinimumWindow.java
+++ b/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java
@@ -1,4 +1,4 @@
-package com.thealgorithms.datastructures.stacks;
+package com.thealgorithms.stacks;
import java.util.Arrays;
import java.util.Stack;
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/NextGraterElement.java b/src/main/java/com/thealgorithms/stacks/NextGraterElement.java
similarity index 97%
rename from src/main/java/com/thealgorithms/datastructures/stacks/NextGraterElement.java
rename to src/main/java/com/thealgorithms/stacks/NextGraterElement.java
index 294e436c24a2..0cf56349c662 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/NextGraterElement.java
+++ b/src/main/java/com/thealgorithms/stacks/NextGraterElement.java
@@ -1,4 +1,4 @@
-package com.thealgorithms.datastructures.stacks;
+package com.thealgorithms.stacks;
import java.util.Arrays;
import java.util.Stack;
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/NextSmallerElement.java b/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java
similarity index 97%
rename from src/main/java/com/thealgorithms/datastructures/stacks/NextSmallerElement.java
rename to src/main/java/com/thealgorithms/stacks/NextSmallerElement.java
index b25e5346d574..84263d986508 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/NextSmallerElement.java
+++ b/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java
@@ -1,4 +1,4 @@
-package com.thealgorithms.datastructures.stacks;
+package com.thealgorithms.stacks;
import java.util.Arrays;
import java.util.Stack;
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/PostfixToInfix.java b/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java
similarity index 98%
rename from src/main/java/com/thealgorithms/datastructures/stacks/PostfixToInfix.java
rename to src/main/java/com/thealgorithms/stacks/PostfixToInfix.java
index 0d67a7939513..0c674ec02a1e 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/PostfixToInfix.java
+++ b/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java
@@ -1,4 +1,4 @@
-package com.thealgorithms.datastructures.stacks;
+package com.thealgorithms.stacks;
import java.util.Stack;
diff --git a/src/main/java/com/thealgorithms/others/StackPostfixNotation.java b/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java
similarity index 98%
rename from src/main/java/com/thealgorithms/others/StackPostfixNotation.java
rename to src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java
index 0e8ad58c41b3..d4b7c9222e1d 100644
--- a/src/main/java/com/thealgorithms/others/StackPostfixNotation.java
+++ b/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java
@@ -1,4 +1,4 @@
-package com.thealgorithms.others;
+package com.thealgorithms.stacks;
import java.util.Scanner;
import java.util.Stack;
diff --git a/src/test/java/com/thealgorithms/others/CalculateMaxOfMinTest.java b/src/test/java/com/thealgorithms/stacks/CalculateMaxOfMinTest.java
similarity index 79%
rename from src/test/java/com/thealgorithms/others/CalculateMaxOfMinTest.java
rename to src/test/java/com/thealgorithms/stacks/CalculateMaxOfMinTest.java
index e80cf9127e29..4cb1f48dce4a 100644
--- a/src/test/java/com/thealgorithms/others/CalculateMaxOfMinTest.java
+++ b/src/test/java/com/thealgorithms/stacks/CalculateMaxOfMinTest.java
@@ -1,8 +1,7 @@
-package com.thealgorithms.others;
+package com.thealgorithms.stacks;
import static org.junit.jupiter.api.Assertions.*;
-import com.thealgorithms.datastructures.stacks.CalculateMaxOfMin;
import org.junit.jupiter.api.Test;
public class CalculateMaxOfMinTest {
@@ -11,48 +10,48 @@ public class CalculateMaxOfMinTest {
void testForOneElement() {
int[] a = {10, 20, 30, 50, 10, 70, 30};
int k = CalculateMaxOfMin.calculateMaxOfMin(a);
- assertTrue(k == 70);
+ assertEquals(70, k);
}
@Test
void testForTwoElements() {
int[] a = {5, 3, 2, 6, 3, 2, 6};
int k = CalculateMaxOfMin.calculateMaxOfMin(a);
- assertTrue(k == 6);
+ assertEquals(6, k);
}
@Test
void testForThreeElements() {
int[] a = {10, 10, 10, 10, 10, 10, 10};
int k = CalculateMaxOfMin.calculateMaxOfMin(a);
- assertTrue(k == 10);
+ assertEquals(10, k);
}
@Test
void testForFourElements() {
int[] a = {70, 60, 50, 40, 30, 20};
int k = CalculateMaxOfMin.calculateMaxOfMin(a);
- assertTrue(k == 70);
+ assertEquals(70, k);
}
@Test
void testForFiveElements() {
int[] a = {50};
int k = CalculateMaxOfMin.calculateMaxOfMin(a);
- assertTrue(k == 50);
+ assertEquals(50, k);
}
@Test
void testForSixElements() {
int[] a = {1, 4, 7, 9, 2, 4, 6};
int k = CalculateMaxOfMin.calculateMaxOfMin(a);
- assertTrue(k == 9);
+ assertEquals(9, k);
}
@Test
void testForSevenElements() {
int[] a = {-1, -5, -7, -9, -12, -14};
int k = CalculateMaxOfMin.calculateMaxOfMin(a);
- assertTrue(k == -1);
+ assertEquals(-1, k);
}
}
diff --git a/src/test/java/com/thealgorithms/others/StackPostfixNotationTest.java b/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java
similarity index 90%
rename from src/test/java/com/thealgorithms/others/StackPostfixNotationTest.java
rename to src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java
index 9256e2bc44e2..4857529e49a5 100644
--- a/src/test/java/com/thealgorithms/others/StackPostfixNotationTest.java
+++ b/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java
@@ -1,8 +1,7 @@
-package com.thealgorithms.others;
+package com.thealgorithms.stacks;
import static java.util.Map.entry;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.*;
import java.util.Map;
import org.junit.jupiter.api.Test;
From 12b6c292438cac17a19154335bb6066676876b20 Mon Sep 17 00:00:00 2001
From: Manan Solanki <76104205+Manan-09@users.noreply.github.com>
Date: Wed, 20 Sep 2023 01:23:53 +0530
Subject: [PATCH 0005/1151] #4367 Enhance Knapsack problem (#4368)
* Enhance Knapsack problem
* Linter solved
* Linter solved
* Remove DynamicProgrammingKnapsack file, duplicate of Knapsack file
* Add null input testcase
* Linter resolved
* Updated meaningful test names
* Add check for negative weightCapacity
* Linter resolved
* Linter resolved
* Add check for non-positive weight
* Linter resolved
* fix: use proper formatting
* fix: use proper formatting
* fix: use proper formatting (I hope this will work now)
Sorry for the previous mess.
* Code review comments
* Code review comments
* Code review comments
* Code review comments
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../DyanamicProgrammingKnapsack.java | 36 ---------
.../dynamicprogramming/Knapsack.java | 69 ++++++++++------
.../dynamicprogramming/KnapsackTest.java | 81 +++++++++++++++++++
3 files changed, 124 insertions(+), 62 deletions(-)
delete mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/DyanamicProgrammingKnapsack.java
create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/DyanamicProgrammingKnapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/DyanamicProgrammingKnapsack.java
deleted file mode 100644
index 042dff375acd..000000000000
--- a/src/main/java/com/thealgorithms/dynamicprogramming/DyanamicProgrammingKnapsack.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.thealgorithms.dynamicprogramming;
-
-// A Dynamic Programming based solution
-// for 0-1 Knapsack problem
-public class DyanamicProgrammingKnapsack {
- // Returns the maximum value that can
- // be put in a knapsack of capacity W
- static int knapSack(int W, int[] wt, int[] val, int n) {
- int i, w;
- int[][] K = new int[n + 1][W + 1];
-
- // Build table K[][] in bottom up manner
- for (i = 0; i <= n; i++) {
- for (w = 0; w <= W; w++) {
- if (i == 0 || w == 0) {
- K[i][w] = 0;
- } else if (wt[i - 1] <= w) {
- K[i][w] = Math.max(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w]);
- } else {
- K[i][w] = K[i - 1][w];
- }
- }
- }
-
- return K[n][W];
- }
-
- // Driver code
- public static void main(String[] args) {
- int[] val = new int[] {60, 100, 120};
- int[] wt = new int[] {10, 20, 30};
- int W = 50;
- int n = val.length;
- System.out.println(knapSack(W, wt, val, n));
- }
-}
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java
index 712a028ee960..134561766830 100644
--- a/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java
@@ -1,38 +1,55 @@
package com.thealgorithms.dynamicprogramming;
+import java.util.Arrays;
+
/**
- * A DynamicProgramming based solution for 0-1 Knapsack problem
+ * A Dynamic Programming based solution for the 0-1 Knapsack problem.
+ * This class provides a method, `knapSack`, that calculates the maximum value that can be
+ * obtained from a given set of items with weights and values, while not exceeding a
+ * given weight capacity.
+ *
+ * @see 0-1 Knapsack Problem
*/
-public class Knapsack {
+public final class Knapsack {
+
+ private Knapsack() {
+ }
- private static int knapSack(int W, int[] wt, int[] val, int n) throws IllegalArgumentException {
- if (wt == null || val == null) {
- throw new IllegalArgumentException();
+ private static void throwIfInvalidInput(final int weightCapacity, final int[] weights, final int[] values) {
+ if (weightCapacity < 0) {
+ throw new IllegalArgumentException("Weight capacity should not be negative.");
}
- int i, w;
- int[][] rv = new int[n + 1][W + 1]; // rv means return value
-
- // Build table rv[][] in bottom up manner
- for (i = 0; i <= n; i++) {
- for (w = 0; w <= W; w++) {
- if (i == 0 || w == 0) {
- rv[i][w] = 0;
- } else if (wt[i - 1] <= w) {
- rv[i][w] = Math.max(val[i - 1] + rv[i - 1][w - wt[i - 1]], rv[i - 1][w]);
- } else {
- rv[i][w] = rv[i - 1][w];
+ if (weights == null || values == null || weights.length != values.length) {
+ throw new IllegalArgumentException("Input arrays must not be null and must have the same length.");
+ }
+ if (Arrays.stream(weights).anyMatch(w -> w <= 0)) {
+ throw new IllegalArgumentException("Input array should not contain non-positive weight(s).");
+ }
+ }
+
+ /**
+ * Solves the 0-1 Knapsack problem using Dynamic Programming.
+ *
+ * @param weightCapacity The maximum weight capacity of the knapsack.
+ * @param weights An array of item weights.
+ * @param values An array of item values.
+ * @return The maximum value that can be obtained without exceeding the weight capacity.
+ * @throws IllegalArgumentException If the input arrays are null or have different lengths.
+ */
+ public static int knapSack(final int weightCapacity, final int[] weights, final int[] values) throws IllegalArgumentException {
+ throwIfInvalidInput(weightCapacity, weights, values);
+
+ // DP table to store the state of the maximum possible return for a given weight capacity.
+ int[] dp = new int[weightCapacity + 1];
+
+ for (int i = 0; i < values.length; i++) {
+ for (int w = weightCapacity; w > 0; w--) {
+ if (weights[i] <= w) {
+ dp[w] = Math.max(dp[w], dp[w - weights[i]] + values[i]);
}
}
}
- return rv[n][W];
- }
-
- // Driver program to test above function
- public static void main(String[] args) {
- int[] val = new int[] {50, 100, 130};
- int[] wt = new int[] {10, 20, 40};
- int W = 50;
- System.out.println(knapSack(W, wt, val, val.length));
+ return dp[weightCapacity];
}
}
diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java
new file mode 100644
index 000000000000..3ff733db7e15
--- /dev/null
+++ b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java
@@ -0,0 +1,81 @@
+package com.thealgorithms.dynamicprogramming;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+public class KnapsackTest {
+ @Test
+ public void testKnapSackBasic() {
+ int[] weights = {2, 3, 4, 5};
+ int[] values = {3, 4, 5, 6};
+ int weightCapacity = 5;
+ int expected = 7; // Maximum value should be 7 (items 1 and 4).
+ int result = Knapsack.knapSack(weightCapacity, weights, values);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testKnapSackEmpty() {
+ int[] weights = {};
+ int[] values = {};
+ int weightCapacity = 10;
+ int expected = 0; // With no items, the result should be 0.
+ int result = Knapsack.knapSack(weightCapacity, weights, values);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testKnapSackNoCapacity() {
+ int[] weights = {2, 3, 4};
+ int[] values = {3, 4, 5};
+ int weightCapacity = 0;
+ int expected = 0; // With no capacity, the result should be 0.
+ int result = Knapsack.knapSack(weightCapacity, weights, values);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testKnapSackMaxCapacity() {
+ int[] weights = {2, 3, 4, 5};
+ int[] values = {3, 4, 5, 6};
+ int weightCapacity = 10;
+ int expected = 13; // Maximum value should be 13 (items 1, 3, and 4).
+ int result = Knapsack.knapSack(weightCapacity, weights, values);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testKnapSackThrowsForInputsOfDifferentLength() {
+ int[] weights = {2, 3, 4};
+ int[] values = {3, 4, 5, 6}; // Different length values array.
+ int weightCapacity = 5;
+ assertThrows(IllegalArgumentException.class, () -> { Knapsack.knapSack(weightCapacity, weights, values); });
+ }
+
+ @Test
+ public void testKnapSackThrowsForNullInputs() {
+ int[] weights = {2, 3, 4};
+ int[] values = {3, 4, 6};
+ int weightCapacity = 5;
+ assertThrows(IllegalArgumentException.class, () -> { Knapsack.knapSack(weightCapacity, null, values); });
+ assertThrows(IllegalArgumentException.class, () -> { Knapsack.knapSack(weightCapacity, weights, null); });
+ }
+
+ @Test
+ public void testKnapSackThrowsForNegativeCapacity() {
+ int[] weights = {2, 3, 4, 5};
+ int[] values = {3, 4, 5, 6};
+ int weightCapacity = -5;
+ assertThrows(IllegalArgumentException.class, () -> { Knapsack.knapSack(weightCapacity, weights, values); });
+ }
+
+ @Test
+ public void testKnapSackThrowsForNegativeWeight() {
+ int[] weights = {2, 0, 4};
+ int[] values = {3, 4, 6};
+ int weightCapacity = 5;
+ assertThrows(IllegalArgumentException.class, () -> { Knapsack.knapSack(weightCapacity, weights, values); });
+ }
+}
From 906cd877315774e59c527c09c842bc1891886ac8 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Wed, 20 Sep 2023 19:38:37 +0200
Subject: [PATCH 0006/1151] style: avoid wildcard imports (#4386)
* style: import `assertEquals` explicitly
* fix: import `assertThrows`
---
src/test/java/com/thealgorithms/maths/FactorialTest.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/test/java/com/thealgorithms/maths/FactorialTest.java b/src/test/java/com/thealgorithms/maths/FactorialTest.java
index b22ad535a234..b38dc45589ee 100644
--- a/src/test/java/com/thealgorithms/maths/FactorialTest.java
+++ b/src/test/java/com/thealgorithms/maths/FactorialTest.java
@@ -1,6 +1,7 @@
package com.thealgorithms.maths;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
From fbe348b105a06258a81538023698117e2bb116cb Mon Sep 17 00:00:00 2001
From: Ansh Shah <60037118+govardhanshah456@users.noreply.github.com>
Date: Thu, 21 Sep 2023 11:35:26 +0530
Subject: [PATCH 0007/1151] #4382 Bug Fix (#4384)
* #4382 Bug Fix
* #4382 Bug Fix
* Made Requested Changes
* Made Requested Changes
* Made Requested Changes
* Made Requested Changes
* Made Requested Changes
* Made Requested Changes
* Made Requested Changes
* Update src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../misc/MedianOfRunningArray.java | 42 +++--
.../misc/MedianOfRunningArrayTest.java | 161 ++++++++++++++++++
2 files changed, 181 insertions(+), 22 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java
diff --git a/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java b/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java
index 84dff89eaa8b..61fbfa82003f 100644
--- a/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java
+++ b/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java
@@ -8,13 +8,13 @@
*/
public class MedianOfRunningArray {
- private PriorityQueue p1;
- private PriorityQueue p2;
+ private PriorityQueue maxHeap;
+ private PriorityQueue minHeap;
// Constructor
public MedianOfRunningArray() {
- this.p1 = new PriorityQueue<>(Collections.reverseOrder()); // Max Heap
- this.p2 = new PriorityQueue<>(); // Min Heap
+ this.maxHeap = new PriorityQueue<>(Collections.reverseOrder()); // Max Heap
+ this.minHeap = new PriorityQueue<>(); // Min Heap
}
/*
@@ -22,32 +22,30 @@ public MedianOfRunningArray() {
and upper half to min heap
*/
public void insert(Integer e) {
- p2.add(e);
- if (p2.size() - p1.size() > 1) {
- p1.add(p2.remove());
+ if (!minHeap.isEmpty() && e < minHeap.peek()) {
+ maxHeap.offer(e);
+ if (maxHeap.size() > minHeap.size() + 1) {
+ minHeap.offer(maxHeap.poll());
+ }
+ } else {
+ minHeap.offer(e);
+ if (minHeap.size() > maxHeap.size() + 1) {
+ maxHeap.offer(minHeap.poll());
+ }
}
}
/*
Returns median at any given point
*/
- public Integer median() {
- if (p1.size() == p2.size()) {
- return (p1.peek() + p2.peek()) / 2;
+ public double median() {
+ if (maxHeap.isEmpty() && minHeap.isEmpty()) {
+ throw new IllegalArgumentException("Enter at least 1 element, Median of empty list is not defined!");
}
- return p1.size() > p2.size() ? p1.peek() : p2.peek();
- }
-
- public static void main(String[] args) {
- /*
- Testing the median function
- */
- MedianOfRunningArray p = new MedianOfRunningArray();
- int[] arr = {10, 7, 4, 9, 2, 3, 11, 17, 14};
- for (int i = 0; i < 9; i++) {
- p.insert(arr[i]);
- System.out.print(p.median() + " ");
+ if (maxHeap.size() == minHeap.size()) {
+ return (maxHeap.peek() + minHeap.peek()) / 2.0;
}
+ return maxHeap.size() > minHeap.size() ? maxHeap.peek() * 1.0 : minHeap.peek() * 1.0;
}
}
diff --git a/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java b/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java
new file mode 100644
index 000000000000..96cdc77e92a2
--- /dev/null
+++ b/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java
@@ -0,0 +1,161 @@
+package com.thealgorithms.misc;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test case for Two sum Problem.
+ * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
+ */
+
+public class MedianOfRunningArrayTest {
+ private static final String EXCEPTION_MESSAGE = "Enter at least 1 element, Median of empty list is not defined!";
+
+ @Test
+ public void testWhenInvalidInoutProvidedShouldThrowException() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> stream.median());
+ assertEquals(exception.getMessage(), EXCEPTION_MESSAGE);
+ }
+
+ @Test
+ public void testWithNegativeValues() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ stream.insert(-1);
+ assertEquals(-1, stream.median());
+ stream.insert(-2);
+ assertEquals(-1.5, stream.median());
+ stream.insert(-3);
+ assertEquals(-2, stream.median());
+ }
+
+ @Test
+ public void testWithSingleValues() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ stream.insert(-1);
+ assertEquals(-1, stream.median());
+ }
+
+ @Test
+ public void testWithRandomValues() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ stream.insert(10);
+ assertEquals(10.0, stream.median());
+
+ stream.insert(5);
+ assertEquals(7.5, stream.median());
+
+ stream.insert(20);
+ assertEquals(10.0, stream.median());
+
+ stream.insert(15);
+ assertEquals(12.5, stream.median());
+
+ stream.insert(25);
+ assertEquals(15.0, stream.median());
+
+ stream.insert(30);
+ assertEquals(17.5, stream.median());
+
+ stream.insert(35);
+ assertEquals(20.0, stream.median());
+
+ stream.insert(1);
+ assertEquals(17.5, stream.median());
+ }
+
+ @Test
+ public void testWithNegativeAndPositiveValues() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ stream.insert(-1);
+ assertEquals(-1, stream.median());
+ stream.insert(2);
+ assertEquals(0.5, stream.median());
+ stream.insert(-3);
+ assertEquals(-1, stream.median());
+ }
+
+ @Test
+ public void testWithDuplicateValues() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ stream.insert(-1);
+ assertEquals(-1, stream.median());
+ stream.insert(-1);
+ assertEquals(-1, stream.median());
+ stream.insert(-1);
+ assertEquals(-1, stream.median());
+ }
+
+ @Test
+ public void testWithDuplicateValuesB() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ stream.insert(10);
+ stream.insert(20);
+ stream.insert(10);
+ stream.insert(10);
+ stream.insert(20);
+ stream.insert(0);
+ stream.insert(50);
+ assertEquals(10, stream.median());
+ }
+
+ @Test
+ public void testWithLargeValues() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ stream.insert(1000000);
+ assertEquals(1000000, stream.median());
+ stream.insert(12000);
+ assertEquals(506000, stream.median());
+ stream.insert(15000000);
+ assertEquals(1000000, stream.median());
+ stream.insert(2300000);
+ assertEquals(1650000.00, stream.median());
+ }
+
+ @Test
+ public void testWithLargeCountOfValues() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ for (int i = 1; i <= 1000; i++) stream.insert(i);
+ assertEquals(500.5, stream.median());
+ }
+
+ @Test
+ public void testWithThreeValuesInDescendingOrder() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ stream.insert(30);
+ stream.insert(20);
+ stream.insert(10);
+ assertEquals(20.0, stream.median());
+ }
+
+ @Test
+ public void testWithThreeValuesInOrder() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ stream.insert(10);
+ stream.insert(20);
+ stream.insert(30);
+ assertEquals(20.0, stream.median());
+ }
+
+ @Test
+ public void testWithThreeValuesNotInOrderA() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ stream.insert(30);
+ stream.insert(10);
+ stream.insert(20);
+ assertEquals(20.0, stream.median());
+ }
+
+ @Test
+ public void testWithThreeValuesNotInOrderB() {
+ MedianOfRunningArray stream = new MedianOfRunningArray();
+ stream.insert(20);
+ stream.insert(10);
+ stream.insert(30);
+ assertEquals(20.0, stream.median());
+ }
+}
From 8803b1ead59716617b221a8ef92a90cc0ec067c2 Mon Sep 17 00:00:00 2001
From: Manan Solanki <76104205+Manan-09@users.noreply.github.com>
Date: Sat, 23 Sep 2023 13:56:14 +0530
Subject: [PATCH 0008/1151] #4387 Enhance Minimum sum partition problem
implementation (#4394)
* Enhance Minimum sum partition problem implementation
* Linter resolved
* Linter resolved
* Code review comments
* Code review comments
* Add validation for non-negative numbers
* Linter resolved
* style: fix formiatting
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../MinimumSumPartition.java | 106 ++++++------------
.../MinimumSumPartitionTest.java | 44 ++++++++
2 files changed, 81 insertions(+), 69 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java b/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java
index c15c0186fc62..52308c23cf1c 100644
--- a/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java
@@ -1,89 +1,57 @@
package com.thealgorithms.dynamicprogramming;
-// Partition a set into two subsets such that the difference of subset sums is minimum
+import java.util.Arrays;
/*
-Input: arr[] = {1, 6, 11, 5}
-Output: 1
+Given an array of non-negative integers , partition the array in two subset that
+difference in sum of elements for both subset minimum.
+Return the minimum difference in sum of these subsets you can achieve.
+
+Input: array[] = {1, 6, 11, 4}
+Output: 0
Explanation:
-Subset1 = {1, 5, 6}, sum of Subset1 = 12
+Subset1 = {1, 4, 6}, sum of Subset1 = 11
Subset2 = {11}, sum of Subset2 = 11
-Input: arr[] = {36, 7, 46, 40}
+Input: array[] = {36, 7, 46, 40}
Output: 23
Explanation:
Subset1 = {7, 46} ; sum of Subset1 = 53
Subset2 = {36, 40} ; sum of Subset2 = 76
*/
-public class MinimumSumPartition {
-
- public static int subSet(int[] arr) {
- int n = arr.length;
- int sum = getSum(arr);
- boolean[][] dp = new boolean[n + 1][sum + 1];
- for (int i = 0; i <= n; i++) {
- dp[i][0] = true;
- }
- for (int j = 0; j <= sum; j++) {
- dp[0][j] = false;
- }
-
- // fill dp array
- for (int i = 1; i <= n; i++) {
- for (int j = 1; j <= sum; j++) {
- if (arr[i - 1] < j) {
- dp[i][j] = dp[i - 1][j - arr[i - 1]] || dp[i - 1][j];
- } else if (arr[i - 1] == j) {
- dp[i][j] = true;
- } else {
- dp[i][j] = dp[i - 1][j];
- }
- }
- }
-
- // fill the index array
- int[] index = new int[sum];
- int p = 0;
- for (int i = 0; i <= sum / 2; i++) {
- if (dp[n][i]) {
- index[p++] = i;
- }
- }
-
- return getMin(index, sum);
+public final class MinimumSumPartition {
+ private MinimumSumPartition() {
}
- /**
- * Calculate sum of array elements
- *
- * @param arr the array
- * @return sum of given array
- */
- public static int getSum(int[] arr) {
- int sum = 0;
- for (int temp : arr) {
- sum += temp;
+ private static void throwIfInvalidInput(final int[] array) {
+ if (Arrays.stream(array).anyMatch(a -> a < 0)) {
+ throw new IllegalArgumentException("Input array should not contain negative number(s).");
}
- return sum;
}
- public static int getMin(int[] arr, int sum) {
- if (arr.length == 0) {
- return 0;
- }
- int min = Integer.MAX_VALUE;
- for (int temp : arr) {
- min = Math.min(min, sum - 2 * temp);
- }
- return min;
- }
+ public static int minimumSumPartition(final int[] array) {
+ throwIfInvalidInput(array);
+ int sum = Arrays.stream(array).sum();
+ boolean[] dp = new boolean[sum / 2 + 1];
+ dp[0] = true; // Base case , don't select any element from array
- /**
- * Driver Code
- */
- public static void main(String[] args) {
- assert subSet(new int[] {1, 6, 11, 5}) == 1;
- assert subSet(new int[] {36, 7, 46, 40}) == 23;
- assert subSet(new int[] {1, 2, 3, 9}) == 3;
+ // Find the closest sum of subset array that we can achieve which is closest to half of sum of full array
+ int closestPartitionSum = 0;
+
+ for (int i = 0; i < array.length; i++) {
+ for (int j = sum / 2; j > 0; j--) {
+ if (array[i] <= j) {
+ dp[j] = dp[j] || dp[j - array[i]];
+ }
+ if (dp[j]) {
+ closestPartitionSum = Math.max(closestPartitionSum, j);
+ }
+ }
+ }
+ /*
+ Difference in sum = Big partition sum - Small partition sum
+ = ( Total sum - Small partition sum) - Small partition sum
+ */
+ return sum - (2 * closestPartitionSum);
}
}
diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java
new file mode 100644
index 000000000000..1f14320244ea
--- /dev/null
+++ b/src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java
@@ -0,0 +1,44 @@
+package com.thealgorithms.dynamicprogramming;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+class MinimumSumPartitionTest {
+ @Test
+ public void testMinimumSumPartitionWithEvenSum() {
+ int[] array = {1, 6, 11, 4};
+ assertEquals(0, MinimumSumPartition.minimumSumPartition(array));
+ }
+
+ @Test
+ public void testMinimumSumPartitionWithOddSum() {
+ int[] array = {36, 7, 46, 40};
+ assertEquals(23, MinimumSumPartition.minimumSumPartition(array));
+ }
+
+ @Test
+ public void testMinimumSumPartitionWithSingleElement() {
+ int[] array = {7};
+ assertEquals(7, MinimumSumPartition.minimumSumPartition(array));
+ }
+
+ @Test
+ public void testMinimumSumPartitionWithLargeNumbers() {
+ int[] array = {100, 200, 300, 400, 500};
+ assertEquals(100, MinimumSumPartition.minimumSumPartition(array));
+ }
+
+ @Test
+ public void testMinimumSumPartitionWithEmptyArray() {
+ int[] array = {};
+ assertEquals(0, MinimumSumPartition.minimumSumPartition(array));
+ }
+
+ @Test
+ public void testMinimumSumPartitionThrowsForNegativeArray() {
+ int[] array = {4, 1, -6, 7};
+ assertThrows(IllegalArgumentException.class, () -> { MinimumSumPartition.minimumSumPartition(array); });
+ }
+}
From d3a32135dc9230125599c38d56849228f99a3b11 Mon Sep 17 00:00:00 2001
From: Ansh Shah <60037118+govardhanshah456@users.noreply.github.com>
Date: Sun, 24 Sep 2023 11:20:43 +0530
Subject: [PATCH 0009/1151] Make `MedianOfRunningArray` Generic (#4392)
---
.../misc/MedianOfRunningArray.java | 24 ++--
.../misc/MedianOfRunningArrayByte.java | 8 ++
.../misc/MedianOfRunningArrayDouble.java | 8 ++
.../misc/MedianOfRunningArrayFloat.java | 8 ++
.../misc/MedianOfRunningArrayInteger.java | 8 ++
.../misc/MedianOfRunningArrayLong.java | 8 ++
.../misc/MedianOfRunningArrayTest.java | 104 ++++++++++++------
7 files changed, 124 insertions(+), 44 deletions(-)
create mode 100644 src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java
create mode 100644 src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java
create mode 100644 src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java
create mode 100644 src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java
create mode 100644 src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java
diff --git a/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java b/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java
index 61fbfa82003f..62013ee31183 100644
--- a/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java
+++ b/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java
@@ -6,10 +6,10 @@
/**
* @author shrutisheoran
*/
-public class MedianOfRunningArray {
+public abstract class MedianOfRunningArray> {
- private PriorityQueue maxHeap;
- private PriorityQueue minHeap;
+ private PriorityQueue maxHeap;
+ private PriorityQueue minHeap;
// Constructor
public MedianOfRunningArray() {
@@ -21,8 +21,8 @@ public MedianOfRunningArray() {
Inserting lower half of array to max Heap
and upper half to min heap
*/
- public void insert(Integer e) {
- if (!minHeap.isEmpty() && e < minHeap.peek()) {
+ public void insert(final T e) {
+ if (!minHeap.isEmpty() && e.compareTo(minHeap.peek()) < 0) {
maxHeap.offer(e);
if (maxHeap.size() > minHeap.size() + 1) {
minHeap.offer(maxHeap.poll());
@@ -38,14 +38,16 @@ public void insert(Integer e) {
/*
Returns median at any given point
*/
- public double median() {
+ public T median() {
if (maxHeap.isEmpty() && minHeap.isEmpty()) {
throw new IllegalArgumentException("Enter at least 1 element, Median of empty list is not defined!");
+ } else if (maxHeap.size() == minHeap.size()) {
+ T maxHeapTop = maxHeap.peek();
+ T minHeapTop = minHeap.peek();
+ return calculateAverage(maxHeapTop, minHeapTop);
}
-
- if (maxHeap.size() == minHeap.size()) {
- return (maxHeap.peek() + minHeap.peek()) / 2.0;
- }
- return maxHeap.size() > minHeap.size() ? maxHeap.peek() * 1.0 : minHeap.peek() * 1.0;
+ return maxHeap.size() > minHeap.size() ? maxHeap.peek() : minHeap.peek();
}
+
+ public abstract T calculateAverage(T a, T b);
}
diff --git a/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java b/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java
new file mode 100644
index 000000000000..668f651e7251
--- /dev/null
+++ b/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java
@@ -0,0 +1,8 @@
+package com.thealgorithms.misc;
+
+public final class MedianOfRunningArrayByte extends MedianOfRunningArray {
+ @Override
+ public Byte calculateAverage(final Byte a, final Byte b) {
+ return (byte) ((a + b) / 2);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java b/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java
new file mode 100644
index 000000000000..9d743de51643
--- /dev/null
+++ b/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java
@@ -0,0 +1,8 @@
+package com.thealgorithms.misc;
+
+public final class MedianOfRunningArrayDouble extends MedianOfRunningArray {
+ @Override
+ public Double calculateAverage(final Double a, final Double b) {
+ return (a + b) / 2.0d;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java b/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java
new file mode 100644
index 000000000000..a667abf6121b
--- /dev/null
+++ b/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java
@@ -0,0 +1,8 @@
+package com.thealgorithms.misc;
+
+public final class MedianOfRunningArrayFloat extends MedianOfRunningArray {
+ @Override
+ public Float calculateAverage(final Float a, final Float b) {
+ return (a + b) / 2.0f;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java b/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java
new file mode 100644
index 000000000000..7154ba073136
--- /dev/null
+++ b/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java
@@ -0,0 +1,8 @@
+package com.thealgorithms.misc;
+
+public final class MedianOfRunningArrayInteger extends MedianOfRunningArray {
+ @Override
+ public Integer calculateAverage(final Integer a, final Integer b) {
+ return (a + b) / 2;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java b/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java
new file mode 100644
index 000000000000..1f138c6313fb
--- /dev/null
+++ b/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java
@@ -0,0 +1,8 @@
+package com.thealgorithms.misc;
+
+public final class MedianOfRunningArrayLong extends MedianOfRunningArray {
+ @Override
+ public Long calculateAverage(final Long a, final Long b) {
+ return (a + b) / 2L;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java b/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java
index 96cdc77e92a2..90910d511ca0 100644
--- a/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java
+++ b/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java
@@ -1,15 +1,13 @@
package com.thealgorithms.misc;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import org.apache.commons.lang3.tuple.Pair;
import org.junit.jupiter.api.Test;
/**
- * Test case for Two sum Problem.
- * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
+ * Test case for Median Of Running Array Problem.
+ * @author Ansh Shah (https://github.com/govardhanshah456)
*/
public class MedianOfRunningArrayTest {
@@ -17,71 +15,71 @@ public class MedianOfRunningArrayTest {
@Test
public void testWhenInvalidInoutProvidedShouldThrowException() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> stream.median());
assertEquals(exception.getMessage(), EXCEPTION_MESSAGE);
}
@Test
public void testWithNegativeValues() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
stream.insert(-1);
assertEquals(-1, stream.median());
stream.insert(-2);
- assertEquals(-1.5, stream.median());
+ assertEquals(-1, stream.median());
stream.insert(-3);
assertEquals(-2, stream.median());
}
@Test
public void testWithSingleValues() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
stream.insert(-1);
assertEquals(-1, stream.median());
}
@Test
public void testWithRandomValues() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
stream.insert(10);
- assertEquals(10.0, stream.median());
+ assertEquals(10, stream.median());
stream.insert(5);
- assertEquals(7.5, stream.median());
+ assertEquals(7, stream.median());
stream.insert(20);
- assertEquals(10.0, stream.median());
+ assertEquals(10, stream.median());
stream.insert(15);
- assertEquals(12.5, stream.median());
+ assertEquals(12, stream.median());
stream.insert(25);
- assertEquals(15.0, stream.median());
+ assertEquals(15, stream.median());
stream.insert(30);
- assertEquals(17.5, stream.median());
+ assertEquals(17, stream.median());
stream.insert(35);
- assertEquals(20.0, stream.median());
+ assertEquals(20, stream.median());
stream.insert(1);
- assertEquals(17.5, stream.median());
+ assertEquals(17, stream.median());
}
@Test
public void testWithNegativeAndPositiveValues() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
stream.insert(-1);
assertEquals(-1, stream.median());
stream.insert(2);
- assertEquals(0.5, stream.median());
+ assertEquals(0, stream.median());
stream.insert(-3);
assertEquals(-1, stream.median());
}
@Test
public void testWithDuplicateValues() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
stream.insert(-1);
assertEquals(-1, stream.median());
stream.insert(-1);
@@ -92,7 +90,7 @@ public void testWithDuplicateValues() {
@Test
public void testWithDuplicateValuesB() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
stream.insert(10);
stream.insert(20);
stream.insert(10);
@@ -105,7 +103,7 @@ public void testWithDuplicateValuesB() {
@Test
public void testWithLargeValues() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
stream.insert(1000000);
assertEquals(1000000, stream.median());
stream.insert(12000);
@@ -113,49 +111,89 @@ public void testWithLargeValues() {
stream.insert(15000000);
assertEquals(1000000, stream.median());
stream.insert(2300000);
- assertEquals(1650000.00, stream.median());
+ assertEquals(1650000, stream.median());
}
@Test
public void testWithLargeCountOfValues() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
for (int i = 1; i <= 1000; i++) stream.insert(i);
- assertEquals(500.5, stream.median());
+ assertEquals(500, stream.median());
}
@Test
public void testWithThreeValuesInDescendingOrder() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
stream.insert(30);
stream.insert(20);
stream.insert(10);
- assertEquals(20.0, stream.median());
+ assertEquals(20, stream.median());
}
@Test
public void testWithThreeValuesInOrder() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
stream.insert(10);
stream.insert(20);
stream.insert(30);
- assertEquals(20.0, stream.median());
+ assertEquals(20, stream.median());
}
@Test
public void testWithThreeValuesNotInOrderA() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
stream.insert(30);
stream.insert(10);
stream.insert(20);
- assertEquals(20.0, stream.median());
+ assertEquals(20, stream.median());
}
@Test
public void testWithThreeValuesNotInOrderB() {
- MedianOfRunningArray stream = new MedianOfRunningArray();
+ var stream = new MedianOfRunningArrayInteger();
stream.insert(20);
stream.insert(10);
stream.insert(30);
- assertEquals(20.0, stream.median());
+ assertEquals(20, stream.median());
+ }
+
+ @Test
+ public void testWithFloatValues() {
+ var stream = new MedianOfRunningArrayFloat();
+ stream.insert(20.0f);
+ assertEquals(20.0f, stream.median());
+ stream.insert(10.5f);
+ assertEquals(15.25f, stream.median());
+ stream.insert(30.0f);
+ assertEquals(20.0f, stream.median());
+ }
+
+ @Test
+ public void testWithByteValues() {
+ var stream = new MedianOfRunningArrayByte();
+ stream.insert((byte) 120);
+ assertEquals((byte) 120, stream.median());
+ stream.insert((byte) -120);
+ assertEquals((byte) 0, stream.median());
+ stream.insert((byte) 127);
+ assertEquals((byte) 120, stream.median());
+ }
+
+ @Test
+ public void testWithLongValues() {
+ var stream = new MedianOfRunningArrayLong();
+ stream.insert(120000000L);
+ assertEquals(120000000L, stream.median());
+ stream.insert(92233720368547757L);
+ assertEquals(46116860244273878L, stream.median());
+ }
+
+ @Test
+ public void testWithDoubleValues() {
+ var stream = new MedianOfRunningArrayDouble();
+ stream.insert(12345.67891);
+ assertEquals(12345.67891, stream.median());
+ stream.insert(23456789.98);
+ assertEquals(Double.valueOf(11734567.83), stream.median(), .01);
}
}
From c1476d796c54e4f9ee47f91895a7d830461f9a68 Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Sun, 24 Sep 2023 08:26:05 +0200
Subject: [PATCH 0010/1151] Make FindMin more efficient (#4389)
---
src/main/java/com/thealgorithms/maths/FindMin.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/FindMin.java b/src/main/java/com/thealgorithms/maths/FindMin.java
index 7764c1c049b4..cab03628a75a 100644
--- a/src/main/java/com/thealgorithms/maths/FindMin.java
+++ b/src/main/java/com/thealgorithms/maths/FindMin.java
@@ -34,10 +34,10 @@ public static int findMin(int[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array must be non-empty.");
}
- int min = Integer.MAX_VALUE;
- for (final var value : array) {
- if (value < min) {
- min = value;
+ int min = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] < min) {
+ min = array[i];
}
}
return min;
From ad4be217d43fdaa38c994d7397ba5e732de26096 Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Sun, 24 Sep 2023 09:11:36 +0200
Subject: [PATCH 0011/1151] Update FindMax.java (#4396)
---
src/main/java/com/thealgorithms/maths/FindMax.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/FindMax.java b/src/main/java/com/thealgorithms/maths/FindMax.java
index 559424fe15df..8587e3abb198 100644
--- a/src/main/java/com/thealgorithms/maths/FindMax.java
+++ b/src/main/java/com/thealgorithms/maths/FindMax.java
@@ -34,10 +34,10 @@ public static int findMax(int[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array must be non-empty.");
}
- int max = Integer.MIN_VALUE;
- for (final var value : array) {
- if (value > max) {
- max = value;
+ int max = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] > max) {
+ max = array[i];
}
}
return max;
From fa77b50ef9edb90949db77de76116c1a3ede10a1 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Sun, 24 Sep 2023 10:25:19 +0200
Subject: [PATCH 0012/1151] style: make `FindMax` a proper utilty class (#4398)
---
.../java/com/thealgorithms/maths/FindMax.java | 25 +++----------------
1 file changed, 3 insertions(+), 22 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/FindMax.java b/src/main/java/com/thealgorithms/maths/FindMax.java
index 8587e3abb198..76bde5ff600f 100644
--- a/src/main/java/com/thealgorithms/maths/FindMax.java
+++ b/src/main/java/com/thealgorithms/maths/FindMax.java
@@ -1,26 +1,7 @@
package com.thealgorithms.maths;
-import java.util.Arrays;
-import java.util.Random;
-
-public class FindMax {
-
- /**
- * Driver Code
- */
- public static void main(String[] args) {
- Random random = new Random();
-
- /* random size */
- int size = random.nextInt(100) + 1;
- int[] array = new int[size];
-
- /* init array with random numbers */
- for (int i = 0; i < size; i++) {
- array[i] = random.nextInt() % 100;
- }
-
- assert Arrays.stream(array).max().getAsInt() == findMax(array);
+public final class FindMax {
+ private FindMax() {
}
/**
@@ -30,7 +11,7 @@ public static void main(String[] args) {
* @exception IllegalArgumentException input array is empty
* @return the maximum value stored in the input array
*/
- public static int findMax(int[] array) {
+ public static int findMax(final int[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array must be non-empty.");
}
From d6024f9cd49e3dc33576cb949ba379e62ad42528 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Sun, 24 Sep 2023 12:25:28 +0200
Subject: [PATCH 0013/1151] Make `FindMin` a proper utilty class (#4397)
---
.../java/com/thealgorithms/maths/FindMin.java | 25 +++----------------
1 file changed, 3 insertions(+), 22 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/FindMin.java b/src/main/java/com/thealgorithms/maths/FindMin.java
index cab03628a75a..10a03c801098 100644
--- a/src/main/java/com/thealgorithms/maths/FindMin.java
+++ b/src/main/java/com/thealgorithms/maths/FindMin.java
@@ -1,26 +1,7 @@
package com.thealgorithms.maths;
-import java.util.Arrays;
-import java.util.Random;
-
-public class FindMin {
-
- /**
- * Driver Code
- */
- public static void main(String[] args) {
- Random random = new Random();
-
- /* random size */
- int size = random.nextInt(100) + 1;
- int[] array = new int[size];
-
- /* init array with random numbers */
- for (int i = 0; i < size; i++) {
- array[i] = random.nextInt() % 100;
- }
-
- assert Arrays.stream(array).min().getAsInt() == findMin(array);
+public final class FindMin {
+ private FindMin() {
}
/**
@@ -30,7 +11,7 @@ public static void main(String[] args) {
* @exception IllegalArgumentException input array is empty
* @return the mimum value stored in the input array
*/
- public static int findMin(int[] array) {
+ public static int findMin(final int[] array) {
if (array.length == 0) {
throw new IllegalArgumentException("array must be non-empty.");
}
From 9d8a0f36cfa45e96589532b5487b654d4cbb278d Mon Sep 17 00:00:00 2001
From: Manan Solanki <76104205+Manan-09@users.noreply.github.com>
Date: Mon, 25 Sep 2023 19:55:16 +0530
Subject: [PATCH 0014/1151] Optimize MinimumPathSum (#4400)
---
.../dynamicprogramming/MinimumPathSum.java | 62 +++++++++----------
.../MinimumPathSumTest.java | 8 ++-
2 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java b/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java
index cd1f25a46664..98773de92f6b 100644
--- a/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java
@@ -12,9 +12,8 @@
(m)
Find the path where its sum is the smallest.
-All numbers given are positive.
The Time Complexity of your algorithm should be smaller than or equal to O(mn).
-The Space Complexity of your algorithm should be smaller than or equal to O(mn).
+The Space Complexity of your algorithm should be smaller than or equal to O(n).
You can only move from the top left corner to the down right corner.
You can only move one step down or right.
@@ -25,46 +24,41 @@ The Space Complexity of your algorithm should be smaller than or equal to O(mn).
For more information see https://www.geeksforgeeks.org/maximum-path-sum-matrix/
*/
-public class MinimumPathSum {
+public final class MinimumPathSum {
- public void testRegular() {
- int[][] grid = {{1, 3, 1}, {1, 5, 1}, {4, 2, 1}};
- System.out.println(minimumPathSum(grid));
+ private MinimumPathSum() {
}
- public void testLessColumns() {
- int[][] grid = {{1, 2}, {5, 6}, {1, 1}};
- System.out.println(minimumPathSum(grid));
- }
-
- public void testLessRows() {
- int[][] grid = {{2, 3, 3}, {7, 2, 1}};
- System.out.println(minimumPathSum(grid));
- }
+ public static int minimumPathSum(final int[][] grid) {
+ int numRows = grid.length;
+ int numCols = grid[0].length;
- public void testOneRowOneColumn() {
- int[][] grid = {{2}};
- System.out.println(minimumPathSum(grid));
- }
-
- public static int minimumPathSum(int[][] grid) {
- int m = grid.length, n = grid[0].length;
- if (n == 0) {
+ if (numCols == 0) {
return 0;
}
- int[][] dp = new int[m][n];
- dp[0][0] = grid[0][0];
- for (int i = 0; i < n - 1; i++) {
- dp[0][i + 1] = dp[0][i] + grid[0][i + 1];
- }
- for (int i = 0; i < m - 1; i++) {
- dp[i + 1][0] = dp[i][0] + grid[i + 1][0];
+
+ int[] dp = new int[numCols];
+
+ // Initialize the first element of the dp array
+ dp[0] = grid[0][0];
+
+ // Calculate the minimum path sums for the first row
+ for (int col = 1; col < numCols; col++) {
+ dp[col] = dp[col - 1] + grid[0][col];
}
- for (int i = 1; i < m; i++) {
- for (int j = 1; j < n; j++) {
- dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
+
+ // Calculate the minimum path sums for the remaining rows
+ for (int row = 1; row < numRows; row++) {
+ // Update the minimum path sum for the first column
+ dp[0] += grid[row][0];
+
+ for (int col = 1; col < numCols; col++) {
+ // Choose the minimum path sum from the left or above
+ dp[col] = Math.min(dp[col - 1], dp[col]) + grid[row][col];
}
}
- return dp[m - 1][n - 1];
+
+ // Return the minimum path sum for the last cell in the grid
+ return dp[numCols - 1];
}
}
diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java
index 25e2d8372b49..5c722c3c0036 100644
--- a/src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java
+++ b/src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java
@@ -1,6 +1,6 @@
package com.thealgorithms.dynamicprogramming;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
@@ -41,4 +41,10 @@ public void testMinimumPathSumWithDiffRowAndColumnGrid() {
int[][] grid = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
assertEquals(30, MinimumPathSum.minimumPathSum(grid));
}
+
+ @Test
+ public void testMinimumPathSumWithNegativeNumberGrid() {
+ int[][] grid = {{1, 3, 1}, {3, 4, 1}, {4, -3, 1}};
+ assertEquals(6, MinimumPathSum.minimumPathSum(grid));
+ }
}
From 01157f299c20011cf6227039909b9ecc3a99341c Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Mon, 25 Sep 2023 20:38:54 +0200
Subject: [PATCH 0015/1151] Add negative FindMinTest (#4388)
---
.../com/thealgorithms/maths/FindMinTest.java | 28 ++++++++-----------
1 file changed, 11 insertions(+), 17 deletions(-)
diff --git a/src/test/java/com/thealgorithms/maths/FindMinTest.java b/src/test/java/com/thealgorithms/maths/FindMinTest.java
index 7599b9029bf1..7884b4b79281 100644
--- a/src/test/java/com/thealgorithms/maths/FindMinTest.java
+++ b/src/test/java/com/thealgorithms/maths/FindMinTest.java
@@ -1,30 +1,24 @@
package com.thealgorithms.maths;
-import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
public class FindMinTest {
- @Test
- public void testFindMinValue() {
- assertEquals(1, FindMin.findMin(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
- }
-
- @Test
- public void test1() {
- assertEquals(1, FindMin.findMin(new int[] {1, 3, 5, 7, 9}));
+ @ParameterizedTest
+ @MethodSource("provideStringsForIsBlank")
+ void numberTests(int expected, int[] input) {
+ Assertions.assertEquals(expected, FindMin.findMin(input));
}
- @Test
- public void test2() {
- assertEquals(0, FindMin.findMin(new int[] {0, 192, 384, 576}));
- }
-
- @Test
- public void test3() {
- assertEquals(0, FindMin.findMin(new int[] {10, 10, 0, 10}));
+ private static Stream provideStringsForIsBlank() {
+ return Stream.of(Arguments.of(1, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), Arguments.of(5, new int[] {5, 5, 5, 5, 5}), Arguments.of(0, new int[] {0, 192, 384, 576}), Arguments.of(-1, new int[] {-1, 2, 5, 10}), Arguments.of(-10, new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}));
}
@Test
From cada67b1eb58558b08049b84ee93a15de7867e4b Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Mon, 25 Sep 2023 21:10:04 +0200
Subject: [PATCH 0016/1151] Remove array len + Math.max (#4401)
---
.../java/com/thealgorithms/maths/FindMaxRecursion.java | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java b/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
index c38da196f46e..f6acafd2684c 100644
--- a/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
+++ b/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
@@ -17,7 +17,7 @@ public static void main(String[] args) {
array[i] = rand.nextInt() % 100;
}
- assert max(array, array.length) == Arrays.stream(array).max().getAsInt();
+ assert max(array) == Arrays.stream(array).max().getAsInt();
assert max(array, 0, array.length - 1) == Arrays.stream(array).max().getAsInt();
}
@@ -39,17 +39,16 @@ public static int max(int[] array, int low, int high) {
int leftMax = max(array, low, mid); // get max in [low, mid]
int rightMax = max(array, mid + 1, high); // get max in [mid+1, high]
- return Math.max(leftMax, rightMax);
+ return leftMax < rightMax ? rightMax : leftMax;
}
/**
* Get max of array using recursion algorithm
*
* @param array contains elements
- * @param len length of given array
* @return max value of {@code array}
*/
- public static int max(int[] array, int len) {
- return len == 1 ? array[0] : Math.max(max(array, len - 1), array[len - 1]);
+ public static int max(int[] array) {
+ return array.length == 1 ? array[0] : max(array, 0, array.length);
}
}
From 02bac7e3d4f152a2369dca61cc1b2a1664bbcf24 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Tue, 26 Sep 2023 07:41:27 +0200
Subject: [PATCH 0017/1151] Add test case with minimum not at index 0 (#4403)
---
src/test/java/com/thealgorithms/maths/FindMinTest.java | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/test/java/com/thealgorithms/maths/FindMinTest.java b/src/test/java/com/thealgorithms/maths/FindMinTest.java
index 7884b4b79281..e713c0191ea1 100644
--- a/src/test/java/com/thealgorithms/maths/FindMinTest.java
+++ b/src/test/java/com/thealgorithms/maths/FindMinTest.java
@@ -12,13 +12,14 @@
public class FindMinTest {
@ParameterizedTest
- @MethodSource("provideStringsForIsBlank")
+ @MethodSource("inputStream")
void numberTests(int expected, int[] input) {
Assertions.assertEquals(expected, FindMin.findMin(input));
}
- private static Stream provideStringsForIsBlank() {
- return Stream.of(Arguments.of(1, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), Arguments.of(5, new int[] {5, 5, 5, 5, 5}), Arguments.of(0, new int[] {0, 192, 384, 576}), Arguments.of(-1, new int[] {-1, 2, 5, 10}), Arguments.of(-10, new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}));
+ private static Stream inputStream() {
+ return Stream.of(Arguments.of(1, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), Arguments.of(5, new int[] {5, 5, 5, 5, 5}), Arguments.of(0, new int[] {0, 192, 384, 576}), Arguments.of(-1, new int[] {-1, 2, 5, 10}), Arguments.of(-10, new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}),
+ Arguments.of(-4, new int[] {4, -3, 8, 9, -4, -4, 10}));
}
@Test
From bf777fff8f075cccff32223cd2f5c085adb5b09e Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Tue, 26 Sep 2023 17:31:16 +0200
Subject: [PATCH 0018/1151] Remove array len + Math.min (#4405)
---
.../java/com/thealgorithms/maths/FindMinRecursion.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/FindMinRecursion.java b/src/main/java/com/thealgorithms/maths/FindMinRecursion.java
index 66400d23db3f..71d7795b7e47 100644
--- a/src/main/java/com/thealgorithms/maths/FindMinRecursion.java
+++ b/src/main/java/com/thealgorithms/maths/FindMinRecursion.java
@@ -21,7 +21,7 @@ public static void main(String[] args) {
}
assert min(array, 0, array.length - 1) == Arrays.stream(array).min().getAsInt();
- assert min(array, array.length) == Arrays.stream(array).min().getAsInt();
+ assert min(array) == Arrays.stream(array).min().getAsInt();
}
/**
@@ -42,7 +42,7 @@ public static int min(int[] array, int low, int high) {
int leftMin = min(array, low, mid); // get min in [low, mid]
int rightMin = min(array, mid + 1, high); // get min in [mid+1, high]
- return Math.min(leftMin, rightMin);
+ return leftMin > rightMin ? rightMin : leftMin;
}
/**
@@ -52,7 +52,7 @@ public static int min(int[] array, int low, int high) {
* @param len length of given array
* @return min value of {@code array}
*/
- public static int min(int[] array, int len) {
- return len == 1 ? array[0] : Math.min(min(array, len - 1), array[len - 1]);
+ public static int min(int[] array) {
+ return array.length == 1 ? array[0] : min(array, 0, array.length);
}
}
From 8583ca3b40ffb21d3005b7c354737e1ac9a3b39c Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Tue, 26 Sep 2023 21:36:56 +0200
Subject: [PATCH 0019/1151] Changing MaxFindTest (#4406)
* Changing MaxFindTest
* Update FindMaxTest.java
* Update FindMaxTest.java
* Update FindMaxTest.java
* Apply suggestions from code review
- add test case with unsorted array,
- test FindMax
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../com/thealgorithms/maths/FindMaxTest.java | 23 +++++++++----------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/src/test/java/com/thealgorithms/maths/FindMaxTest.java b/src/test/java/com/thealgorithms/maths/FindMaxTest.java
index 17f8d454c5ff..a863a2c8586b 100644
--- a/src/test/java/com/thealgorithms/maths/FindMaxTest.java
+++ b/src/test/java/com/thealgorithms/maths/FindMaxTest.java
@@ -1,25 +1,24 @@
package com.thealgorithms.maths;
-import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
public class FindMaxTest {
- @Test
- public void testFindMax0() {
- assertEquals(10, FindMax.findMax(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
+ @ParameterizedTest
+ @MethodSource("inputStream")
+ void numberTests(int expected, int[] input) {
+ Assertions.assertEquals(expected, FindMax.findMax(input));
}
- @Test
- public void testFindMax1() {
- assertEquals(7, FindMax.findMax(new int[] {6, 3, 5, 1, 7, 4, 1}));
- }
-
- @Test
- public void testFindMax2() {
- assertEquals(10, FindMax.findMax(new int[] {10, 0}));
+ private static Stream inputStream() {
+ return Stream.of(Arguments.of(10, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), Arguments.of(5, new int[] {5, 5, 5, 5, 5}), Arguments.of(0, new int[] {-1, 0}), Arguments.of(-1, new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}), Arguments.of(9, new int[] {3, -2, 3, 9, -4, -4, 8}));
}
@Test
From 1cf193c7f416cc7763261d9b5d02d451fa6473df Mon Sep 17 00:00:00 2001
From: Andrii Siriak
Date: Wed, 27 Sep 2023 10:10:03 +0300
Subject: [PATCH 0020/1151] Remove @siriak from CODEOWNERS
---
.github/CODEOWNERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index c298ce670806..0706d623599a 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @siriak @yanglbme @debasishbsws @vil02 @BamaCharanChhandogi
+* @yanglbme @debasishbsws @vil02 @BamaCharanChhandogi
From 566c27a996f48a94916170c159ae735546b39c42 Mon Sep 17 00:00:00 2001
From: Janmesh Singh <68192323+janmeshjs@users.noreply.github.com>
Date: Wed, 27 Sep 2023 15:24:52 +0530
Subject: [PATCH 0021/1151] WildcardMatching Added (#4404)
* Added WildcardMatching DP
* Wildcard Matching update
* Updated WildcardMatching
* Added WildcardMatchingTests
* WildcardMatching update
* Clang-formatting done
* WildcardMatching_Clang-formatting done
* WildcardMatching
---
.../dynamicprogramming/WildcardMatching.java | 55 +++++++++++++++++++
.../WildcardMatchingTest.java | 26 +++++++++
2 files changed, 81 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java
create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java b/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java
new file mode 100644
index 000000000000..a938634cdfd2
--- /dev/null
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java
@@ -0,0 +1,55 @@
+/**
+ *
+ * Author: Janmesh Singh
+ * Github: https://github.com/janmeshjs
+
+ * Problem Statement: To determine if the pattern matches the text.
+ * The pattern can include two special wildcard characters:
+ * ' ? ': Matches any single character.
+ * ' * ': Matches zero or more of any character sequence.
+ *
+ * Use DP to return True if the pattern matches the entire text and False otherwise
+ *
+ */
+
+package com.thealgorithms.dynamicprogramming;
+
+public class WildcardMatching {
+
+ public static boolean isMatch(String text, String pattern) {
+ int m = text.length();
+ int n = pattern.length();
+
+ // Create a DP table to store intermediate results
+ boolean[][] dp = new boolean[m + 1][n + 1];
+
+ // Base case: an empty pattern matches an empty text
+ dp[0][0] = true;
+
+ // Handle patterns starting with '*'
+ for (int j = 1; j <= n; j++) {
+ if (pattern.charAt(j - 1) == '*') {
+ dp[0][j] = dp[0][j - 1];
+ }
+ }
+
+ // Fill the DP table
+ for (int i = 1; i <= m; i++) {
+ for (int j = 1; j <= n; j++) {
+ char textChar = text.charAt(i - 1);
+ char patternChar = pattern.charAt(j - 1);
+
+ if (patternChar == textChar || patternChar == '?') {
+ dp[i][j] = dp[i - 1][j - 1];
+ } else if (patternChar == '*') {
+ // '*' can match zero or more characters
+ dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
+ } else {
+ dp[i][j] = false;
+ }
+ }
+ }
+ // The result is in the bottom-right cell of the DP table
+ return dp[m][n];
+ }
+}
diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java
new file mode 100644
index 000000000000..8d91af663ec5
--- /dev/null
+++ b/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java
@@ -0,0 +1,26 @@
+package com.thealgorithms.dynamicprogramming;
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class WildcardMatchingTest {
+
+ @Test
+ public void testMatchingPattern() {
+ assertTrue(WildcardMatching.isMatch("aa", "a*"));
+ assertTrue(WildcardMatching.isMatch("adceb", "*a*b"));
+ }
+
+ @Test
+ public void testNonMatchingPattern() {
+ assertFalse(WildcardMatching.isMatch("cb", "?a"));
+ assertFalse(WildcardMatching.isMatch("acdcb", "a*c?b"));
+ assertFalse(WildcardMatching.isMatch("mississippi", "m*issi*iss?*i"));
+ }
+
+ @Test
+ public void testEmptyPattern() {
+ assertTrue(WildcardMatching.isMatch("", ""));
+ assertFalse(WildcardMatching.isMatch("abc", ""));
+ }
+}
From ea0eef128db5b3e5e1f9d58cb8a7e009cd508ead Mon Sep 17 00:00:00 2001
From: Arin <136636751+asapekia@users.noreply.github.com>
Date: Thu, 28 Sep 2023 22:00:41 +0530
Subject: [PATCH 0022/1151] corrected test file name (#4422)
---
.../bitmanipulation/{SetBit.java => SetBitTest.java} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename src/test/java/com/thealgorithms/bitmanipulation/{SetBit.java => SetBitTest.java} (100%)
diff --git a/src/test/java/com/thealgorithms/bitmanipulation/SetBit.java b/src/test/java/com/thealgorithms/bitmanipulation/SetBitTest.java
similarity index 100%
rename from src/test/java/com/thealgorithms/bitmanipulation/SetBit.java
rename to src/test/java/com/thealgorithms/bitmanipulation/SetBitTest.java
From e5d33f35651e8b46ba2318dbd934dc3eeb81507b Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Sat, 30 Sep 2023 10:06:45 +0200
Subject: [PATCH 0023/1151] Add SingleBitOperations (#4415)
* SingleBitOperators
* Tests
* Update SingleBitOperatorTest.java
* Update SingleBitOperators.java
* Update SingleBitOperators.java
* Update SingleBitOperators.java
* Update SingleBitOperatorTest.java
* deliting files
* Update SingleBitOperators.java
* Update SingleBitOperatorTest.java
* Update SingleBitOperators.java
* Update SingleBitOperators.java
* Update SingleBitOperatorTest.java
* Update SingleBitOperatorTest.java
* Update and rename SingleBitOperators.java to SingleBitOperator.java
* Update SingleBitOperatorTest.java
* Update SingleBitOperator.java
* Update SingleBitOperator.java
* Update SingleBitOperator.java
* style: declare private default constructor
* fix: remove `SetBitTest.java`
* Update and rename SingleBitOperator.java to SingleBitOperations.java
* Update SingleBitOperatorTest.java
* Update SingleBitOperations.java
* Update and rename SingleBitOperatorTest.java to SingleBitOperationsTest.java
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../bitmanipulation/ClearBit.java | 11 ------
.../thealgorithms/bitmanipulation/SetBit.java | 10 ------
.../bitmanipulation/SingleBitOperations.java | 34 +++++++++++++++++++
.../bitmanipulation/ClearBitTest.java | 13 -------
.../bitmanipulation/SetBitTest.java | 13 -------
.../SingleBitOperationsTest.java | 32 +++++++++++++++++
6 files changed, 66 insertions(+), 47 deletions(-)
delete mode 100644 src/main/java/com/thealgorithms/bitmanipulation/ClearBit.java
delete mode 100644 src/main/java/com/thealgorithms/bitmanipulation/SetBit.java
create mode 100644 src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java
delete mode 100644 src/test/java/com/thealgorithms/bitmanipulation/ClearBitTest.java
delete mode 100644 src/test/java/com/thealgorithms/bitmanipulation/SetBitTest.java
create mode 100644 src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/ClearBit.java b/src/main/java/com/thealgorithms/bitmanipulation/ClearBit.java
deleted file mode 100644
index c863c46c53f7..000000000000
--- a/src/main/java/com/thealgorithms/bitmanipulation/ClearBit.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.thealgorithms.bitmanipulation;
-/**
- * Clears the bit located at clear from num
- */
-
-public class ClearBit {
- public static int clearBit(int num, int clear) {
- int mask = ~(1 << clear);
- return num & mask;
- }
-}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/SetBit.java b/src/main/java/com/thealgorithms/bitmanipulation/SetBit.java
deleted file mode 100644
index a48540013a5c..000000000000
--- a/src/main/java/com/thealgorithms/bitmanipulation/SetBit.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.thealgorithms.bitmanipulation;
-/**
- * Sets a specific bit to 1
- */
-
-public class SetBit {
- public static int setBit(int num, int bit) {
- return num | (1 << bit);
- }
-}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java b/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java
new file mode 100644
index 000000000000..b41aeca19af6
--- /dev/null
+++ b/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java
@@ -0,0 +1,34 @@
+package com.thealgorithms.bitmanipulation;
+
+/*
+ * Author: lukasb1b (https://github.com/lukasb1b)
+ */
+
+public final class SingleBitOperations {
+ private SingleBitOperations() {
+ }
+ /**
+ * Flip the bit at position 'bit' in 'num'
+ */
+ public static int flipBit(final int num, final int bit) {
+ return num ^ (1 << bit);
+ }
+ /**
+ * Set the bit at position 'bit' to 1 in the 'num' variable
+ */
+ public static int setBit(final int num, final int bit) {
+ return num | (1 << bit);
+ }
+ /**
+ * Clears the bit located at 'bit' from 'num'
+ */
+ public static int clearBit(final int num, final int bit) {
+ return num & ~(1 << bit);
+ }
+ /**
+ * Get the bit located at 'bit' from 'num'
+ */
+ public static int getBit(final int num, final int bit) {
+ return ((num >> bit) & 1);
+ }
+}
diff --git a/src/test/java/com/thealgorithms/bitmanipulation/ClearBitTest.java b/src/test/java/com/thealgorithms/bitmanipulation/ClearBitTest.java
deleted file mode 100644
index 60f73e9dd73c..000000000000
--- a/src/test/java/com/thealgorithms/bitmanipulation/ClearBitTest.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.thealgorithms.bitmanipulation;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import org.junit.jupiter.api.Test;
-
-public class ClearBitTest {
- @Test
- public void clearBitTest() {
- assertEquals(5, ClearBit.clearBit(7, 1));
- assertEquals(5, ClearBit.clearBit(5, 1));
- }
-}
diff --git a/src/test/java/com/thealgorithms/bitmanipulation/SetBitTest.java b/src/test/java/com/thealgorithms/bitmanipulation/SetBitTest.java
deleted file mode 100644
index b6d2514ed903..000000000000
--- a/src/test/java/com/thealgorithms/bitmanipulation/SetBitTest.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.thealgorithms.bitmanipulation;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import org.junit.jupiter.api.Test;
-
-class SetBitTest {
- @Test
- void testSetBit() {
- assertEquals(5, SetBit.setBit(4, 0));
- assertEquals(3, SetBit.setBit(3, 1));
- }
-}
diff --git a/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java b/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java
new file mode 100644
index 000000000000..a6bb76689ec8
--- /dev/null
+++ b/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java
@@ -0,0 +1,32 @@
+package com.thealgorithms.bitmanipulation;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class SingleBitOperationsTest {
+
+ @Test
+ public void flipBitTest() {
+ assertEquals(1, SingleBitOperations.flipBit(3, 1));
+ assertEquals(11, SingleBitOperations.flipBit(3, 3));
+ }
+
+ @Test
+ public void setBitTest() {
+ assertEquals(5, SingleBitOperations.setBit(4, 0));
+ assertEquals(4, SingleBitOperations.setBit(4, 2));
+ }
+
+ @Test
+ public void clearBitTest() {
+ assertEquals(5, SingleBitOperations.clearBit(7, 1));
+ assertEquals(5, SingleBitOperations.clearBit(5, 1));
+ }
+
+ @Test
+ public void getBitTest() {
+ assertEquals(0, SingleBitOperations.getBit(6, 0));
+ assertEquals(1, SingleBitOperations.getBit(7, 1));
+ }
+}
From ee2629c8ab5c5c27bd728fb02a92a67a74a76cbc Mon Sep 17 00:00:00 2001
From: ANKIT SAHA <85545712+Ankit-Saha08@users.noreply.github.com>
Date: Sun, 1 Oct 2023 16:28:13 +0530
Subject: [PATCH 0024/1151] Update Pangram.java using Java Collections (#4479)
* Update Pangram.java using Java Collections
A simple separate function isPangramOrNot(String s) has been created which implements the Pangram checking of a string using Java Collection Framework approach.
* Update Pangram.java using Java Collections
* Updated some linting errors in Pangram.java
* Update src/main/java/com/thealgorithms/strings/Pangram.java
Co-authored-by: Debasish Biswas
* Updated Pangram.java
Method name updated to - isPangramUsingSet(String s)
* Updated the testcases PangramTest.java
Successfully updated the testcases in this same PR branch
---------
Co-authored-by: Debasish Biswas
---
.../com/thealgorithms/strings/Pangram.java | 18 ++++++++++++++++++
.../com/thealgorithms/strings/PangramTest.java | 5 +++++
2 files changed, 23 insertions(+)
diff --git a/src/main/java/com/thealgorithms/strings/Pangram.java b/src/main/java/com/thealgorithms/strings/Pangram.java
index 4772ac826b5e..9d734579406c 100644
--- a/src/main/java/com/thealgorithms/strings/Pangram.java
+++ b/src/main/java/com/thealgorithms/strings/Pangram.java
@@ -1,5 +1,7 @@
package com.thealgorithms.strings;
+import java.util.HashSet;
+
/**
* Wikipedia: https://en.wikipedia.org/wiki/Pangram
*/
@@ -15,6 +17,22 @@ public static void main(String[] args) {
assert !isPangram("\u0000/\\");
}
+ /**
+ * Checks if a String is considered a Pangram
+ *
+ * @param s The String to check
+ * @return {@code true} if s is a Pangram, otherwise {@code false}
+ */
+ // alternative approach using Java Collection Framework
+ public static boolean isPangramUsingSet(String s) {
+ HashSet alpha = new HashSet();
+ s = s.trim().toLowerCase();
+ for (int i = 0; i < s.length(); i++)
+ if (s.charAt(i) != ' ') alpha.add(s.charAt(i));
+ if (alpha.size() == 26) return true;
+ return false;
+ }
+
/**
* Checks if a String is considered a Pangram
*
diff --git a/src/test/java/com/thealgorithms/strings/PangramTest.java b/src/test/java/com/thealgorithms/strings/PangramTest.java
index 5d138a5ed7fb..7ad79b203b45 100644
--- a/src/test/java/com/thealgorithms/strings/PangramTest.java
+++ b/src/test/java/com/thealgorithms/strings/PangramTest.java
@@ -17,5 +17,10 @@ public void testPangram() {
assertFalse(Pangram.isPangram2("The quick brown fox jumps over the azy dog")); // L is missing
assertFalse(Pangram.isPangram2("+-1234 This string is not alphabetical"));
assertFalse(Pangram.isPangram2("\u0000/\\ Invalid characters are alright too"));
+
+ assertTrue(Pangram.isPangramUsingSet("The quick brown fox jumps over the lazy dog"));
+ assertFalse(Pangram.isPangramUsingSet("The quick brown fox jumps over the azy dog")); // L is missing
+ assertFalse(Pangram.isPangramUsingSet("+-1234 This string is not alphabetical"));
+ assertFalse(Pangram.isPangramUsingSet("\u0000/\\ Invalid characters are alright too"));
}
}
From da687c11cb35d9c13c8d2681796b512e08f59f27 Mon Sep 17 00:00:00 2001
From: Pronay Debnath
Date: Sun, 1 Oct 2023 20:52:51 +0530
Subject: [PATCH 0025/1151] Added [FEATURE REQUEST]
#4457 (#4469)
* Create RecursiveBinarySearch.java
* Update RecursiveBinarySearch.java
* Update RecursiveBinarySearch.java
* Update RecursiveBinarySearch.java
* Update RecursiveBinarySearch.java
* Create ReverseArray.java
* Update RecursiveBinarySearch.java
* Update RecursiveBinarySearch.java
* Create RecursiveBinarySearchTest.java
* Update RecursiveBinarySearchTest.java
* Update RecursiveBinarySearchTest.java
* Delete src/main/java/com/thealgorithms/others/ReverseArray.java
* Update RecursiveBinarySearchTest.java
* Update RecursiveBinarySearchTest.java
* Create ReverseArray.java
* Delete src/main/java/com/thealgorithms/others/ReverseArray.java
* Update RecursiveBinarySearchTest.java
* Update RecursiveBinarySearch.java
---
.../searches/RecursiveBinarySearch.java | 74 +++++++++++++++++++
.../searches/RecursiveBinarySearchTest.java | 40 ++++++++++
2 files changed, 114 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java
create mode 100644 src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java
diff --git a/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java b/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java
new file mode 100644
index 000000000000..8a02b30a9f0e
--- /dev/null
+++ b/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java
@@ -0,0 +1,74 @@
+// Code by Pronay Debnath
+// Created:- 1/10/2023
+// File Name should be RecursiveBinarySearch.java
+// Explanation:- https://www.tutorialspoint.com/java-program-for-binary-search-recursive
+
+import java.util.*;
+
+// Create a SearchAlgorithm class with a generic type
+abstract class SearchAlgorithm> {
+ // Abstract find method to be implemented by subclasses
+ public abstract int find(T[] arr, T target);
+}
+
+public class RecursiveBinarySearch> extends SearchAlgorithm {
+
+ // Override the find method as required
+ @Override
+ public int find(T[] arr, T target) {
+ // Call the recursive binary search function
+ return binsear(arr, 0, arr.length - 1, target);
+ }
+
+ // Recursive binary search function
+ public int binsear(T[] arr, int left, int right, T target) {
+ if (right >= left) {
+ int mid = left + (right - left) / 2;
+
+ // Compare the element at the middle with the target
+ int comparison = arr[mid].compareTo(target);
+
+ // If the element is equal to the target, return its index
+ if (comparison == 0) {
+ return mid;
+ }
+
+ // If the element is greater than the target, search in the left subarray
+ if (comparison > 0) {
+ return binsear(arr, left, mid - 1, target);
+ }
+
+ // Otherwise, search in the right subarray
+ return binsear(arr, mid + 1, right, target);
+ }
+
+ // Element is not present in the array
+ return -1;
+ }
+
+ public static void main(String[] args) {
+ Scanner sc = new Scanner(System.in);
+ // User inputs
+ System.out.print("Enter the number of elements in the array: ");
+ int n = sc.nextInt();
+
+ Integer[] a = new Integer[n]; // You can change the array type as needed
+
+ System.out.println("Enter the elements in sorted order:");
+
+ for (int i = 0; i < n; i++) {
+ a[i] = sc.nextInt();
+ }
+
+ System.out.print("Enter the target element to search for: ");
+ int t = sc.nextInt();
+
+ RecursiveBinarySearch searcher = new RecursiveBinarySearch<>();
+ int res = searcher.find(a, t);
+
+ if (res == -1)
+ System.out.println("Element not found in the array.");
+ else
+ System.out.println("Element found at index " + res);
+ }
+}
diff --git a/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java b/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java
new file mode 100644
index 000000000000..3b2cdead1c6b
--- /dev/null
+++ b/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java
@@ -0,0 +1,40 @@
+// Created by Pronay Debnath
+// Date:- 1/10/2023
+// Test file updated with JUnit tests
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test; // Import the JUnit 5 Test annotation
+
+public class RecursiveBinarySearchTest {
+
+ @Test
+ public void testBinarySearch() {
+ // Create an instance of GenericBinarySearch
+ RecursiveBinarySearch searcher = new RecursiveBinarySearch<>();
+
+ // Test case 1: Element found in the array
+ Integer[] arr1 = {1, 2, 3, 4, 5};
+ int target1 = 3;
+ int result1 = searcher.binsear(arr1, 0, arr1.length - 1, target1);
+ assertEquals(2, result1);
+
+ // Test case 2: Element not found in the array
+ Integer[] arr2 = {1, 2, 3, 4, 5};
+ int target2 = 6;
+ int result2 = searcher.binsear(arr2, 0, arr2.length - 1, target2);
+ assertEquals(-1, result2);
+
+ // Test case 3: Element found at the beginning of the array
+ Integer[] arr3 = {10, 20, 30, 40, 50};
+ int target3 = 10;
+ int result3 = searcher.binsear(arr3, 0, arr3.length - 1, target3);
+ assertEquals(0, result3);
+
+ // Test case 4: Element found at the end of the array
+ Integer[] arr4 = {10, 20, 30, 40, 50};
+ int target4 = 50;
+ int result4 = searcher.binsear(arr4, 0, arr4.length - 1, target4);
+ assertEquals(4, result4);
+ }
+}
From 37b3844b98712d2f46ed2296f307cbb8539dd748 Mon Sep 17 00:00:00 2001
From: Bharath Sanjeevi T <119755499+BharathSanjeeviT@users.noreply.github.com>
Date: Sun, 1 Oct 2023 20:58:37 +0530
Subject: [PATCH 0026/1151] Add `SecondMinMax` (#4432)
* Added Second Min/Max program
* Clang-format-lint error resolved
* Clang-format-error 2
* Added Program to find Second Minimum/Maximum element
* Test File & few changes
* Clang-lint-error resolved
* Maven Build Error Resolved
* Clang-lint-error resolved
* Clang-lint-error resolved 2
* Changes Resolved
* Test Arguements are Streamed
* Clang-lint-error resolved
* incresed code reusability
* Added Program to find Second Min / Max
* Program to find Second Min / Max
* Program to find Second Minimum / Maximum
* Program to find Second Best Number
* style: mark `initialVal` as `final`
* style: resolve `MultipleVariableDeclarations`
Each variable declaration must be in its own statement.
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../com/thealgorithms/maths/SecondMinMax.java | 60 +++++++++++++++++++
.../thealgorithms/maths/SecondMinMaxTest.java | 58 ++++++++++++++++++
2 files changed, 118 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/maths/SecondMinMax.java
create mode 100644 src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java
diff --git a/src/main/java/com/thealgorithms/maths/SecondMinMax.java b/src/main/java/com/thealgorithms/maths/SecondMinMax.java
new file mode 100644
index 000000000000..e5a2d3b89085
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/SecondMinMax.java
@@ -0,0 +1,60 @@
+package com.thealgorithms.maths;
+
+import java.util.function.BiPredicate;
+
+public final class SecondMinMax {
+
+ /**
+ * Utility class for finding second maximum or minimum based on BiPredicate
+ * @exception IllegalArgumentException => if input array is of length less than 2 also if all elements are same
+ * @return the second minimum / maximum value from the input array
+ * @author Bharath Sanjeevi ( https://github.com/BharathSanjeeviT )
+ */
+
+ private SecondMinMax() {
+ }
+
+ private static int secondBest(final int[] arr, final int initialVal, final BiPredicate isBetter) {
+ checkInput(arr);
+ int best = initialVal;
+ int secBest = initialVal;
+ for (final int num : arr) {
+ if (isBetter.test(num, best)) {
+ secBest = best;
+ best = num;
+ } else if ((isBetter.test(num, secBest)) && (num != best)) {
+ secBest = num;
+ }
+ }
+ checkOutput(secBest, initialVal);
+ return secBest;
+ }
+
+ /**
+ * @brief Finds the Second minimum / maximum value from the array
+ * @param arr the input array
+ * @exception IllegalArgumentException => if input array is of length less than 2 also if all elements are same
+ * @return the second minimum / maximum value from the input array
+ * @author Bharath Sanjeevi ( https://github.com/BharathSanjeeviT )
+ */
+
+ public static int findSecondMin(final int[] arr) {
+ return secondBest(arr, Integer.MAX_VALUE, (a, b) -> a < b);
+ }
+
+ public static int findSecondMax(final int[] arr) {
+ return secondBest(arr, Integer.MIN_VALUE, (a, b) -> a > b);
+ }
+
+ private static void checkInput(final int[] arr) {
+ if (arr.length < 2) {
+ throw new IllegalArgumentException("Input array must have length of at least two");
+ }
+ }
+
+ private static void checkOutput(final int secNum, final int initialVal) {
+ if (secNum == initialVal) {
+ throw new IllegalArgumentException("Input array should have at least 2 distinct elements");
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java b/src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java
new file mode 100644
index 000000000000..c744614e5cfa
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java
@@ -0,0 +1,58 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class SecondMinMaxTest {
+
+ private static final String EXP_MSG_ARR_LEN_LESS_2 = "Input array must have length of at least two";
+ private static final String EXP_MSG_ARR_SAME_ELE = "Input array should have at least 2 distinct elements";
+
+ public static class TestCase {
+ public TestCase(final int[] inInputArray, final int inSecondMin, final int inSecondMax) {
+ inputArray = inInputArray;
+ secondMin = inSecondMin;
+ secondMax = inSecondMax;
+ }
+ final int[] inputArray;
+ final int secondMin;
+ final int secondMax;
+ }
+
+ @Test
+ public void testForEmptyInputArray() {
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> SecondMinMax.findSecondMin(new int[] {}));
+ assertEquals(exception.getMessage(), EXP_MSG_ARR_LEN_LESS_2);
+ }
+
+ @Test
+ public void testForArrayWithSingleElement() {
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> SecondMinMax.findSecondMax(new int[] {1}));
+ assertEquals(exception.getMessage(), EXP_MSG_ARR_LEN_LESS_2);
+ }
+
+ @Test
+ public void testForArrayWithSameElements() {
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> SecondMinMax.findSecondMin(new int[] {1, 1, 1, 1}));
+ assertEquals(exception.getMessage(), EXP_MSG_ARR_SAME_ELE);
+ }
+
+ @ParameterizedTest
+ @MethodSource("inputStream")
+ void numberTests(final TestCase tc) {
+ Assertions.assertEquals(tc.secondMax, SecondMinMax.findSecondMax(tc.inputArray));
+ Assertions.assertEquals(tc.secondMin, SecondMinMax.findSecondMin(tc.inputArray));
+ }
+
+ private static Stream inputStream() {
+ return Stream.of(Arguments.of(new TestCase(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 2, 9)), Arguments.of(new TestCase(new int[] {5, 4, 5, 5, 5}, 5, 4)), Arguments.of(new TestCase(new int[] {-1, 0}, 0, -1)),
+ Arguments.of(new TestCase(new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}, -9, -2)), Arguments.of(new TestCase(new int[] {3, -2, 3, 9, -4, -4, 8}, -2, 8)));
+ }
+}
From edb0489440814cd45a4001384b00e8b87c30d6a6 Mon Sep 17 00:00:00 2001
From: Prabhat-Kumar
Date: Sun, 1 Oct 2023 21:31:32 +0530
Subject: [PATCH 0027/1151] [FEATURE] #4486 QuickSort Algo for LinkedList
(#4487)
* Added code to find Articulation Points and Bridges
* tried to solve clang-formant test
* removed new line at EOF to get lint to pass
* feature: Added Ahocorasick Algorithm
* fixed lint using clang-format
* Added QuickSort Algorithm for linked list
* removed datastructures/graphs/ArticulationPointsAndBridges and string/AhoCorasick.java from this branch
* Added datastructures/lists/SinglyLinkedList class, Replaced ListNode class
* Modified some comments
* Added tests in QuickSortLinkedListsTest.java
* removed main as added a test file to test test-cases
* test file for QuickSortLinkedLinst.java
---
.../lists/QuickSortLinkedList.java | 170 ++++++++++++++++++
.../lists/QuickSortLinkedListTest.java | 66 +++++++
2 files changed, 236 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java
create mode 100644 src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java
diff --git a/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java
new file mode 100644
index 000000000000..36b6e9c62cbe
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java
@@ -0,0 +1,170 @@
+package com.thealgorithms.datastructures.lists;
+/*
+ *
+ * @aurthor - Prabhat-Kumar-42
+ * @github - https://github.com/Prabhat-Kumar-42
+ *
+ * Problem :
+ * QuickSort on Linked List
+ *
+ * Note: Taking head as pivot in current implementation.
+ * N represents NULL node
+ * Example:
+ *
+ * -> Given Linked List :
+ * 5 -> 3 -> 8 -> 1 -> 10 -> 2 -> 7 -> 4 -> 9 -> 6
+ *
+ * -> How Sorting will work according to the QuickSort Algo written below
+ *
+ * current pivot : 5
+ * List lessThanPivot : 3 -> 1 -> 2 -> 4
+ * List greaterThanPivot : 5 -> 8 -> 10 -> 7 -> 9 -> 6
+ *
+ * -> reccur for lessThanPivot and greaterThanPivot
+ *
+ * lessThanPivot :
+ * current pivot : 3
+ * lessThanPivot : 1 -> 2
+ * greaterThanPivot : 4
+ *
+ * greaterThanPivot:
+ * current pivot : 5
+ * lessThanPivot : null
+ * greaterThanPivot : 8 -> 10 -> 7 -> 9 -> 6
+ *
+ * By following the above pattern, reccuring tree will form like below :
+ *
+ * List-> 5 -> 3 -> 8 -> 1 -> 10 -> 2 -> 7 -> 4 -> 9 -> 6
+ *
+ * Pivot : 5
+ * /\
+ * / \
+ * / \
+ * / \
+ * / \
+ * List: (3 -> 1 -> 2 -> 4) (5 -> 8 -> 10 -> 7 -> 9 -> 6)
+ * Pivot : 3 5
+ * /\ /\
+ * / \ / \
+ * / \ / \
+ * / \ / \
+ * List: (1 -> 2) (4) (N) (8 -> 10 -> 7 -> 9 -> 6)
+ * Pivot: 1 4 8
+ * /\ /\ /\
+ * / \ / \ / \
+ * / \ / \ / \
+ * List: (N) (2) (N) (N) (6 -> 7) (9 -> 10)
+ * Pivot: 2 6 9
+ * /\ /\ /\
+ * / \ / \ / \
+ * / \ / \ / \
+ * List: (N) (N) (N) (7) (N) (10)
+ * Pivot: 7 10
+ * /\ /\
+ * / \ / \
+ * / \ / \
+ * (N) (N) (N) (N)
+ *
+ *
+ * -> After this the tree will reccur back (or backtrack)
+ * and the returning list from left and right subtree will attach
+ * themselves around pivot.
+ * i.e. ,
+ * (listFromLeftSubTree) -> (Pivot) -> (listFromRightSubtree)
+ *
+ * This will continue until whole list is merged back
+ *
+ * eg :
+ * Megring the above Tree back we get :
+ *
+ * List: (1 -> 2) (4) (6 -> 7) (9 -> 10)
+ * \ / \ /
+ * \ / \ /
+ * \ / \ /
+ * \ / \ /
+ * \ / \ /
+ * \ / \ /
+ * \ / \ /
+ * Pivot: 3 8
+ * List: (1 -> 2 -> 3 -> 4) (6 -> 7 -> 8 -> 9 -> 10)
+ * \ /
+ * \ /
+ * \ /
+ * \ /
+ * \ /
+ * \ /
+ * \ /
+ * \/
+ * Pivot: 5
+ * List: (1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10)
+ *
+ *
+ * -> This will result in a sorted Linked List
+ */
+
+public class QuickSortLinkedList {
+
+ private SinglyLinkedList list = null; // Linked list
+ private Node head = null; // head of the list
+ // Counstructor
+ public QuickSortLinkedList(SinglyLinkedList list) {
+ this.list = list;
+ this.head = list.getHead();
+ }
+
+ // Function to sort a linked list using the Quick Sort algorithm
+ public void sortList() {
+ head = sortList(head);
+ list.setHead(head);
+ }
+ // helper function to apply QuickSort to the stored list
+ public Node sortList(Node head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+
+ // Choose the first element as the pivot
+ Node pivot = head;
+ head = head.next;
+ pivot.next = null;
+
+ Node lessHead = new Node(); // stores the nodes cantaining data less than pivot node
+ Node lessTail = lessHead; // tail of lessHead
+ Node greaterHead = new Node(); // stores the nodes cantaining data greater than pivot node
+ Node greaterTail = greaterHead; // tail of greaterHead
+
+ // Partition the list around the pivot
+ while (head != null) {
+ if (head.value < pivot.value) {
+ lessTail.next = head;
+ lessTail = lessTail.next;
+ } else {
+ greaterTail.next = head;
+ greaterTail = greaterTail.next;
+ }
+ head = head.next;
+ }
+
+ // Seperating lessHead and greaterHead to form two seperate linkedList
+ lessTail.next = null;
+ greaterTail.next = null;
+
+ // Recursively sort the sublists
+ Node sortedLess = sortList(lessHead.next);
+ Node sortedGreater = sortList(greaterHead.next);
+
+ // Combine the sorted sublists and pivot
+ if (sortedLess == null) {
+ pivot.next = sortedGreater;
+ return pivot;
+ } else {
+ Node current = sortedLess;
+ while (current.next != null) {
+ current = current.next;
+ }
+ current.next = pivot;
+ pivot.next = sortedGreater;
+ return sortedLess;
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java b/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java
new file mode 100644
index 000000000000..f4bcfd7fc40d
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java
@@ -0,0 +1,66 @@
+package com.thealgorithms.datastructures.lists;
+
+/**
+ * Test cases for QuickSortLinkedList
+ * Author: Prabhat-Kumar-42
+ * GitHub: https://github.com/Prabhat-Kumar-42
+ */
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class QuickSortLinkedListTest {
+
+ @Test
+ public void testSortEmptyList() {
+ SinglyLinkedList emptyList = new SinglyLinkedList();
+ QuickSortLinkedList sorter = new QuickSortLinkedList(emptyList);
+
+ // Test case: Sorting an empty list should result in an empty list
+ sorter.sortList();
+ assertNull(emptyList.getHead());
+ }
+
+ @Test
+ public void testSortSingleNodeList() {
+ SinglyLinkedList singleNodeList = new SinglyLinkedList();
+ singleNodeList.insert(5);
+ QuickSortLinkedList sorter = new QuickSortLinkedList(singleNodeList);
+
+ // Test case: Sorting a list with a single node should result in the same list
+ sorter.sortList();
+ assertEquals(5, singleNodeList.getHead().value);
+ assertNull(singleNodeList.getHead().next);
+ }
+
+ @Test
+ public void testSortMultipleElementsList() {
+ SinglyLinkedList list = new SinglyLinkedList();
+ list.insert(5);
+ list.insert(3);
+ list.insert(8);
+ list.insert(1);
+ list.insert(10);
+ list.insert(2);
+ list.insert(7);
+ list.insert(4);
+ list.insert(9);
+ list.insert(6);
+ QuickSortLinkedList sorter = new QuickSortLinkedList(list);
+
+ // Test case: Sorting a list with multiple elements
+ sorter.sortList();
+ assertEquals(1, list.getHead().value);
+ assertEquals(2, list.getHead().next.value);
+ assertEquals(3, list.getHead().next.next.value);
+ assertEquals(4, list.getHead().next.next.next.value);
+ assertEquals(5, list.getHead().next.next.next.next.value);
+ assertEquals(6, list.getHead().next.next.next.next.next.value);
+ assertEquals(7, list.getHead().next.next.next.next.next.next.value);
+ assertEquals(8, list.getHead().next.next.next.next.next.next.next.value);
+ assertEquals(9, list.getHead().next.next.next.next.next.next.next.next.value);
+ assertEquals(10, list.getHead().next.next.next.next.next.next.next.next.next.value);
+ assertNull(list.getHead().next.next.next.next.next.next.next.next.next.next);
+ }
+}
From f72b80b116673b3661ae4f55e50c4abbe9c0df49 Mon Sep 17 00:00:00 2001
From: Arin <136636751+asapekia@users.noreply.github.com>
Date: Sun, 1 Oct 2023 21:35:27 +0530
Subject: [PATCH 0028/1151] rewrote as parameterized tests (#4458)
* rewrote as parameterized tests
* formatting issue resolved
* added test with different prime number q
* style: run `clang-format`
* tests: add missing test case
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../searches/RabinKarpAlgorithmTest.java | 56 +++----------------
1 file changed, 9 insertions(+), 47 deletions(-)
diff --git a/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java b/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java
index 6841fdac33f4..4689dccf08fd 100644
--- a/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java
+++ b/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java
@@ -1,56 +1,18 @@
package com.thealgorithms.searches;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
-import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
class RabinKarpAlgorithmTest {
-
RabinKarpAlgorithm RKA = new RabinKarpAlgorithm();
- int q = 101;
-
- @Test
- // valid test case
- public void RabinKarpAlgorithmTestExample() {
- String txt = "This is an example for rabin karp algorithmn";
- String pat = "algorithmn";
- int value = RKA.search(pat, txt, q);
- assertEquals(value, 34);
- }
-
- @Test
- // valid test case
- public void RabinKarpAlgorithmTestFront() {
- String txt = "AAABBDDG";
- String pat = "AAA";
- int value = RKA.search(pat, txt, q);
- assertEquals(value, 0);
- }
-
- @Test
- // valid test case
- public void RabinKarpAlgorithmTestMiddle() {
- String txt = "AAABBCCBB";
- String pat = "BBCC";
- int value = RKA.search(pat, txt, q);
- assertEquals(value, 3);
- }
-
- @Test
- // valid test case
- public void RabinKarpAlgorithmTestLast() {
- String txt = "AAAABBBBCCC";
- String pat = "CCC";
- int value = RKA.search(pat, txt, q);
- assertEquals(value, 8);
- }
- @Test
- // valid test case
- public void RabinKarpAlgorithmTestNotFound() {
- String txt = "ABCBCBCAAB";
- String pat = "AADB";
- int value = RKA.search(pat, txt, q);
- assertEquals(value, -1);
+ @ParameterizedTest
+ @CsvSource({"This is an example for rabin karp algorithmn, algorithmn, 101", "AAABBDDG, AAA, 137", "AAABBCCBB, BBCC, 101", "AAABBCCBB, BBCC, 131", "AAAABBBBCCC, CCC, 41", "ABCBCBCAAB, AADB, 293", "Algorithm The Algorithm, Algorithm, 101"})
+ void RabinKarpAlgorithmTestExample(String txt, String pat, int q) {
+ int indexFromOurAlgorithm = RKA.search(pat, txt, q);
+ int indexFromLinearSearch = txt.indexOf(pat);
+ assertEquals(indexFromOurAlgorithm, indexFromLinearSearch);
}
}
From 8dc5505323708dc0963ba7871afac85cf9db60f7 Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Sun, 1 Oct 2023 20:21:29 +0200
Subject: [PATCH 0029/1151] Add FindMaxRecursionTest (#4431)
* Update FindMaxRecursion.java
* Create FindMaxRecusionTest.java
* Update and rename FindMaxRecusionTest.java to FindMaxRecursionTest.java
* Update FindMaxRecursion.java
* Update FindMaxRecursion.java
* Update src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update FindMaxRecursion.java
* Update FindMaxRecursionTest.java
* Update FindMaxRecursionTest.java
* Update FindMaxRecursion.java
* Update src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update FindMaxRecursion.java
* Update FindMaxRecursion.java
* Update FindMaxRecursion.java
* Update FindMaxRecursion.java
* Update FindMaxRecursion.java
* Update src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../thealgorithms/maths/FindMaxRecursion.java | 30 +++++--------------
.../maths/FindMaxRecursionTest.java | 28 +++++++++++++++++
2 files changed, 36 insertions(+), 22 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java
diff --git a/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java b/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
index f6acafd2684c..574fe5f2b1b8 100644
--- a/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
+++ b/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
@@ -1,26 +1,9 @@
package com.thealgorithms.maths;
-import java.util.Arrays;
-import java.util.Random;
+public final class FindMaxRecursion {
-public class FindMaxRecursion {
-
- public static void main(String[] args) {
- Random rand = new Random();
-
- /* rand size */
- int size = rand.nextInt(100) + 1;
- int[] array = new int[size];
-
- /* init array with rand numbers */
- for (int i = 0; i < size; i++) {
- array[i] = rand.nextInt() % 100;
- }
-
- assert max(array) == Arrays.stream(array).max().getAsInt();
- assert max(array, 0, array.length - 1) == Arrays.stream(array).max().getAsInt();
+ private FindMaxRecursion() {
}
-
/**
* Get max of array using divide and conquer algorithm
*
@@ -29,7 +12,10 @@ public static void main(String[] args) {
* @param high the index of the last element
* @return max of {@code array}
*/
- public static int max(int[] array, int low, int high) {
+ public static int max(final int[] array, final int low, final int high) {
+ if (array.length == 0) {
+ throw new IllegalArgumentException("array must be non-empty.");
+ }
if (low == high) {
return array[low]; // or array[high]
}
@@ -48,7 +34,7 @@ public static int max(int[] array, int low, int high) {
* @param array contains elements
* @return max value of {@code array}
*/
- public static int max(int[] array) {
- return array.length == 1 ? array[0] : max(array, 0, array.length);
+ public static int max(final int[] array) {
+ return max(array, 0, array.length - 1);
}
}
diff --git a/src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java b/src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java
new file mode 100644
index 000000000000..d54cae67209f
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java
@@ -0,0 +1,28 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class FindMaxRecursionTest {
+
+ @ParameterizedTest
+ @MethodSource("inputStream")
+ void numberTests(int expected, int[] input) {
+ Assertions.assertEquals(expected, FindMaxRecursion.max(input));
+ }
+
+ private static Stream inputStream() {
+ return Stream.of(Arguments.of(5, new int[] {5, 5, 5, 5, 5}), Arguments.of(0, new int[] {-1, 0}), Arguments.of(-1, new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}), Arguments.of(9, new int[] {3, -2, 3, 9, -4, -4, 8}), Arguments.of(3, new int[] {3}));
+ }
+
+ @Test
+ public void testFindMaxThrowsExceptionForEmptyInput() {
+ assertThrows(IllegalArgumentException.class, () -> FindMaxRecursion.max(new int[] {}));
+ }
+}
From 628357263720ff7c85a106ec187ccb8296998b0e Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Sun, 1 Oct 2023 21:55:37 +0200
Subject: [PATCH 0030/1151] Ask contributors to create drafts (#4522)
---
.github/pull_request_template.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 01645d5bfedf..ce1d87a2c62e 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,3 +1,11 @@
+
+
- [ ] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
From 536978919dc79af9bf25c57ebb90802d1830784e Mon Sep 17 00:00:00 2001
From: Bama Charan Chhandogi
Date: Tue, 3 Oct 2023 12:13:49 +0530
Subject: [PATCH 0031/1151] Add reverse k group in LinkedList algorithm (#4532)
---
.../datastructures/lists/ReverseKGroup.java | 45 ++++++++++++
.../lists/ReverseKGroupTest.java | 72 +++++++++++++++++++
2 files changed, 117 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java
create mode 100644 src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java
diff --git a/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java b/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java
new file mode 100644
index 000000000000..bd599e2ab91f
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java
@@ -0,0 +1,45 @@
+package com.thealgorithms.datastructures.lists;
+
+/**
+ * Reverse K Group LinkedList (https://www.topcoder.com/thrive/articles/reverse-node-in-k-group)
+ * Author: Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
+ */
+
+public class ReverseKGroup {
+ public int length(Node head) {
+ Node curr = head;
+ int count = 0;
+ while (curr != null) {
+ curr = curr.next;
+ count++;
+ }
+ return count;
+ }
+ // reverse function
+ public Node reverse(Node head, int count, int k) {
+ if (count < k) {
+ return head;
+ }
+ Node prev = null;
+ int count1 = 0;
+ Node curr = head;
+ Node Next = null;
+ while (curr != null && count1 < k) {
+ Next = curr.next;
+ curr.next = prev;
+ prev = curr;
+ curr = Next;
+ count1++;
+ }
+
+ if (Next != null) {
+ head.next = reverse(Next, count - k, k);
+ }
+ return prev;
+ }
+ public Node reverseKGroup(Node head, int k) {
+ int count = length(head);
+ Node ans = reverse(head, count, k);
+ return ans;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java b/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java
new file mode 100644
index 000000000000..8273b890e6ae
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java
@@ -0,0 +1,72 @@
+package com.thealgorithms.datastructures.lists;
+
+/**
+ * Test cases for Reverse K Group LinkedList
+ * Author: Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
+ */
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class ReverseKGroupTest {
+
+ @Test
+ public void testReverseKGroupWithEmptyList() {
+ ReverseKGroup reverser = new ReverseKGroup();
+ assertNull(reverser.reverseKGroup(null, 3));
+ }
+
+ @Test
+ public void testReverseKGroupWithSingleNodeList() {
+ ReverseKGroup reverser = new ReverseKGroup();
+ Node singleNode = new Node(5);
+ Node result = reverser.reverseKGroup(singleNode, 2);
+ assertEquals(5, result.value);
+ assertNull(result.next);
+ }
+
+ @Test
+ public void testReverseKGroupWithKEqualTo2() {
+ ReverseKGroup reverser = new ReverseKGroup();
+
+ // Create a list with multiple elements (1 -> 2 -> 3 -> 4 -> 5)
+ Node head;
+ head = new Node(1);
+ head.next = new Node(2);
+ head.next.next = new Node(3);
+ head.next.next.next = new Node(4);
+ head.next.next.next.next = new Node(5);
+
+ // Test reverse with k=2
+ Node result1 = reverser.reverseKGroup(head, 2);
+ assertEquals(2, result1.value);
+ assertEquals(1, result1.next.value);
+ assertEquals(4, result1.next.next.value);
+ assertEquals(3, result1.next.next.next.value);
+ assertEquals(5, result1.next.next.next.next.value);
+ assertNull(result1.next.next.next.next.next);
+ }
+
+ @Test
+ public void testReverseKGroupWithKEqualTo3() {
+ ReverseKGroup reverser = new ReverseKGroup();
+
+ // Create a list with multiple elements (1 -> 2 -> 3 -> 4 -> 5)
+ Node head;
+ head = new Node(1);
+ head.next = new Node(2);
+ head.next.next = new Node(3);
+ head.next.next.next = new Node(4);
+ head.next.next.next.next = new Node(5);
+
+ // Test reverse with k=3
+ Node result = reverser.reverseKGroup(head, 3);
+ assertEquals(3, result.value);
+ assertEquals(2, result.next.value);
+ assertEquals(1, result.next.next.value);
+ assertEquals(4, result.next.next.next.value);
+ assertEquals(5, result.next.next.next.next.value);
+ assertNull(result.next.next.next.next.next);
+ }
+}
From 5f5a61de872f5894097564ed769299dc5134f011 Mon Sep 17 00:00:00 2001
From: Bama Charan Chhandogi
Date: Tue, 3 Oct 2023 19:46:14 +0530
Subject: [PATCH 0032/1151] Add median of matrix (#4590)
---
.../thealgorithms/misc/MedianOfMatrix.java | 30 ++++++++++++++++
.../misc/MedianOfMatrixtest.java | 34 +++++++++++++++++++
2 files changed, 64 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/misc/MedianOfMatrix.java
create mode 100644 src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java
diff --git a/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java b/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java
new file mode 100644
index 000000000000..4d8b980f2409
--- /dev/null
+++ b/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java
@@ -0,0 +1,30 @@
+package com.thealgorithms.misc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Median of Matrix (https://medium.com/@vaibhav.yadav8101/median-in-a-row-wise-sorted-matrix-901737f3e116)
+ * Author: Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
+ */
+
+public final class MedianOfMatrix {
+
+ public static int median(List> matrix) {
+ // Flatten the matrix into a 1D list
+ List linear = new ArrayList<>();
+ for (List row : matrix) {
+ linear.addAll(row);
+ }
+
+ // Sort the 1D list
+ Collections.sort(linear);
+
+ // Calculate the middle index
+ int mid = (0 + linear.size() - 1) / 2;
+
+ // Return the median
+ return linear.get(mid);
+ }
+}
diff --git a/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java b/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java
new file mode 100644
index 000000000000..c1fa30d6a1cd
--- /dev/null
+++ b/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java
@@ -0,0 +1,34 @@
+package com.thealgorithms.misc;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+public class MedianOfMatrixtest {
+
+ @Test
+ public void testMedianWithOddNumberOfElements() {
+ List> matrix = new ArrayList<>();
+ matrix.add(Arrays.asList(1, 3, 5));
+ matrix.add(Arrays.asList(2, 4, 6));
+ matrix.add(Arrays.asList(7, 8, 9));
+
+ int result = MedianOfMatrix.median(matrix);
+
+ assertEquals(5, result);
+ }
+
+ @Test
+ public void testMedianWithEvenNumberOfElements() {
+ List> matrix = new ArrayList<>();
+ matrix.add(Arrays.asList(2, 4));
+ matrix.add(Arrays.asList(1, 3));
+
+ int result = MedianOfMatrix.median(matrix);
+
+ assertEquals(2, result);
+ }
+}
From 9795bada907a533182496a56ccf8644cc7c274a4 Mon Sep 17 00:00:00 2001
From: Shreyash Kashyap <76607993+SYK-08@users.noreply.github.com>
Date: Tue, 3 Oct 2023 19:52:19 +0530
Subject: [PATCH 0033/1151] Update Readme.md (#4561)
---
.../datastructures/hashmap/Readme.md | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md b/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md
index 7f925989c4f3..252b06ea59b0 100644
--- a/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md
+++ b/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md
@@ -27,27 +27,27 @@ Internally HashMap contains an array of Node and a node is represented as a clas
- V value
- Node next
-It can be seen that the node is containing a reference to its own object. So it’s a linked list.
+It can be seen that the node contains a reference to its object. So it’s a linked list.
## Performance of HashMap
-Performance of HashMap depends on 2 parameters which are named as follows:
+The performance of HashMap depends on 2 parameters which are named as follows:
- Initial Capacity
- Load Factor
-**Initial Capacity**: It is the capacity of HashMap at the time of its creation (It is the number of buckets a HashMap can hold when the HashMap is instantiated). In java, it is 2^4=16 initially, meaning it can hold 16 key-value pairs.
+**Initial Capacity**: It is the capacity of HashMap at the time of its creation (It is the number of buckets a HashMap can hold when the HashMap is instantiated). In Java, it is 2^4=16 initially, meaning it can hold 16 key-value pairs.
-**Load Factor**: It is the percent value of the capacity after which the capacity of Hashmap is to be increased (It is the percentage fill of buckets after which Rehashing takes place). In java, it is 0.75f by default, meaning the rehashing takes place after filling 75% of the capacity.
+**Load Factor**: It is the percent value of the capacity after which the capacity of Hashmap is to be increased (It is the percentage fill of buckets after which Rehashing takes place). In Java, it is 0.75f by default, meaning the rehashing takes place after filling 75% of the capacity.
-**Threshold**: It is the product of Load Factor and Initial Capacity. In java, by default, it is (16 * 0.75 = 12). That is, Rehashing takes place after inserting 12 key-value pairs into the HashMap.
+**Threshold**: It is the product of Load Factor and Initial Capacity. In Java, by default, it is (16 * 0.75 = 12). That is, Rehashing takes place after inserting 12 key-value pairs into the HashMap.
-**Rehashing** : It is the process of doubling the capacity of the HashMap after it reaches its Threshold. In java, HashMap continues to rehash(by default) in the following sequence – 2^4, 2^5, 2^6, 2^7, …. so on.
+**Rehashing** : It is the process of doubling the capacity of the HashMap after it reaches its Threshold. In Java, HashMap continues to rehash(by default) in the following sequence – 2^4, 2^5, 2^6, 2^7, …. so on.
-If the initial capacity is kept higher then rehashing will never be done. But by keeping it higher increases the time complexity of iteration. So it should be chosen very cleverly to increase performance. The expected number of values should be taken into account to set the initial capacity. The most generally preferred load factor value is 0.75 which provides a good deal between time and space costs. The load factor’s value varies between 0 and 1.
+If the initial capacity is kept higher then rehashing will never be done. But keeping it higher increases the time complexity of iteration. So it should be chosen very cleverly to increase performance. The expected number of values should be taken into account to set the initial capacity. The most generally preferred load factor value is 0.75 which provides a good deal between time and space costs. The load factor’s value varies between 0 and 1.
```
Note: From Java 8 onward, Java has started using Self Balancing BST instead of a linked list for chaining.
-The advantage of self-balancing bst is, we get the worst case (when every key maps to the same slot) search time is O(Log n).
+The advantage of self-balancing bst is, that we get the worst case (when every key maps to the same slot) search time is O(Log n).
```
Java has two hash table classes: HashTable and HashMap. In general, you should use a HashMap.
From 329cc3bcf9bc7d43c358f5d7e635a7d9db99890a Mon Sep 17 00:00:00 2001
From: Aman <84791435+Aman28801@users.noreply.github.com>
Date: Tue, 3 Oct 2023 22:12:56 +0530
Subject: [PATCH 0034/1151] Added MirrorOfMatrix.java (#4461)
* Added MirrorOfMatrix.java
* Fixing Linting Issue
* Fixing Linting Issue
* Fixing Linting Issue
* Fixing Linting Issue
* Fixing Linting Issue
* Fixing Linting Issue
* Fixing Linting Issue
* Fixing Linting Issue
* Changes Done
* Update src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Changes Done
* Added MirrorOfMatrixTest.java
* Added MirrorOfMatrixTest.java
* Linting Error in Test
* Linting Error in Test
* Linting Error in Test
* trying to fix build error
* trying to fix build error
* final
* Update src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Changing Description
* Final
* Update src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Final
* Update src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Changes
* Changes
* Linting Issue
* Linting Issue
* Linting Issue
* Changes
* Fixing Minor Linting Issue
* Fixing Minor Linting Issue
* Final
* Update src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Changes
* Linting Issue
* Linting Issue
* Linting Issue
* Linting Issue
* Update src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Changes
* Changes
* fix: use proper size in `checkInput`
* style: basic linting
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Co-authored-by: vil02
---
.../thealgorithms/misc/MirrorOfMatrix.java | 57 +++++++++++++++++++
.../misc/MirrorOfMatrixTest.java | 53 +++++++++++++++++
2 files changed, 110 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
create mode 100644 src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java
diff --git a/src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java b/src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
new file mode 100644
index 000000000000..89dfce3fe049
--- /dev/null
+++ b/src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java
@@ -0,0 +1,57 @@
+package com.thealgorithms.misc;
+
+// Problem Statement
+/*
+We have given an array of m x n (where m is the number of rows and n is the number of columns).
+Print the new matrix in such a way that the new matrix is the mirror image of the original matrix.
+
+The Original matrix is: | The Mirror matrix is:
+1 2 3 | 3 2 1
+4 5 6 | 6 5 4
+7 8 9 | 9 8 7
+
+@author - Aman (https://github.com/Aman28801)
+*/
+
+public final class MirrorOfMatrix {
+ private MirrorOfMatrix() {
+ }
+
+ public static int[][] mirrorMatrix(final int[][] originalMatrix) {
+ if (originalMatrix == null) {
+ // Handle invalid input
+ return null;
+ }
+ if (originalMatrix.length == 0) {
+ return new int[0][0];
+ }
+
+ checkInput(originalMatrix);
+
+ int numRows = originalMatrix.length;
+ int numCols = originalMatrix[0].length;
+
+ int[][] mirroredMatrix = new int[numRows][numCols];
+
+ for (int i = 0; i < numRows; i++) {
+ mirroredMatrix[i] = reverseRow(originalMatrix[i]);
+ }
+ return mirroredMatrix;
+ }
+ private static int[] reverseRow(final int[] inRow) {
+ int[] res = new int[inRow.length];
+ for (int i = 0; i < inRow.length; ++i) {
+ res[i] = inRow[inRow.length - 1 - i];
+ }
+ return res;
+ }
+
+ private static void checkInput(final int[][] matrix) {
+ // Check if all rows have the same number of columns
+ for (int i = 1; i < matrix.length; i++) {
+ if (matrix[i].length != matrix[0].length) {
+ throw new IllegalArgumentException("The input is not a matrix.");
+ }
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java b/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java
new file mode 100644
index 000000000000..0da0cf0f804a
--- /dev/null
+++ b/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java
@@ -0,0 +1,53 @@
+package com.thealgorithms.misc;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+class MirrorOfMatrixTest {
+
+ @Test
+ void testMirrorMatrixRegularMatrix() {
+ int[][] originalMatrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
+ int[][] expectedMirrorMatrix = {{3, 2, 1}, {6, 5, 4}, {9, 8, 7}};
+ int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix);
+ assertArrayEquals(expectedMirrorMatrix, mirroredMatrix);
+ }
+
+ @Test
+ void testMirrorMatrixEmptyMatrix() {
+ int[][] originalMatrix = {};
+ int[][] expectedMirrorMatrix = {};
+ int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix);
+ assertArrayEquals(expectedMirrorMatrix, mirroredMatrix);
+ }
+
+ @Test
+ void testMirrorMatrixSingleElementMatrix() {
+ int[][] originalMatrix = {{42}};
+ int[][] expectedMirrorMatrix = {{42}};
+ int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix);
+ assertArrayEquals(expectedMirrorMatrix, mirroredMatrix);
+ }
+
+ @Test
+ void testMirrorMatrixMultipleRowsOneColumnMatrix() {
+ int[][] originalMatrix = {{1}, {2}, {3}, {4}};
+ int[][] expectedMirrorMatrix = {{1}, {2}, {3}, {4}};
+ int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix);
+ assertArrayEquals(expectedMirrorMatrix, mirroredMatrix);
+ }
+
+ @Test
+ void testMirrorMatrixNullInput() {
+ int[][] originalMatrix = null;
+ assertNull(MirrorOfMatrix.mirrorMatrix(originalMatrix));
+ }
+
+ @Test
+ void testMirrotMarixThrows() {
+ assertThrows(IllegalArgumentException.class, () -> MirrorOfMatrix.mirrorMatrix(new int[][] {{1}, {2, 3}}));
+ }
+}
From 535230acae939a9bb601a82be6f2c20c75687c4d Mon Sep 17 00:00:00 2001
From: Vineet Chotaliya <105866260+Vineetttt@users.noreply.github.com>
Date: Tue, 3 Oct 2023 23:00:18 +0530
Subject: [PATCH 0035/1151] Add Greedy Algorithms (fixes #4493) (#4504)
---
.../greedyalgorithms/ActivitySelection.java | 40 ++++++++++++
.../greedyalgorithms/CoinChange.java | 35 ++++++++++
.../greedyalgorithms/FractionalKnapsack.java | 41 ++++++++++++
.../greedyalgorithms/JobSequencing.java | 65 +++++++++++++++++++
.../ActivitySelectionTest.java | 42 ++++++++++++
.../greedyalgorithms/CoinChangeTest.java | 58 +++++++++++++++++
.../FractionalKnapsackTest.java | 32 +++++++++
.../greedyalgorithms/JobSequencingTest.java | 23 +++++++
8 files changed, 336 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java
create mode 100644 src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java
create mode 100644 src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java
create mode 100644 src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java
create mode 100644 src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java
create mode 100644 src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java
create mode 100644 src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java
create mode 100644 src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java
diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java b/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java
new file mode 100644
index 000000000000..0f704dd6ed55
--- /dev/null
+++ b/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java
@@ -0,0 +1,40 @@
+package com.thealgorithms.greedyalgorithms;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+
+// Problem Link: https://en.wikipedia.org/wiki/Activity_selection_problem
+
+public class ActivitySelection {
+ // Function to perform activity selection
+ public static ArrayList activitySelection(int startTimes[], int endTimes[]) {
+ int n = startTimes.length;
+ int activities[][] = new int[n][3];
+
+ // Create a 2D array to store activities and their start/end times.
+ // Each row: [activity index, start time, end time]
+
+ for (int i = 0; i < n; i++) {
+ activities[i][0] = i; // Assign activity index
+ activities[i][1] = startTimes[i]; // Assign start time
+ activities[i][2] = endTimes[i]; // Assign end time
+ }
+
+ // Sort activities by their end times in ascending order.
+ Arrays.sort(activities, Comparator.comparingDouble(activity -> activity[2]));
+ int lastEndTime;
+ ArrayList selectedActivities = new ArrayList<>();
+ selectedActivities.add(activities[0][0]);
+ lastEndTime = activities[0][2];
+
+ // Iterate through sorted activities to select compatible ones.
+ for (int i = 1; i < n; i++) {
+ if (activities[i][1] >= lastEndTime) {
+ selectedActivities.add(activities[i][0]);
+ lastEndTime = activities[i][2];
+ }
+ }
+ return selectedActivities;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java b/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java
new file mode 100644
index 000000000000..2109e454fa4d
--- /dev/null
+++ b/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java
@@ -0,0 +1,35 @@
+package com.thealgorithms.greedyalgorithms;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+
+// Problem Link : https://en.wikipedia.org/wiki/Change-making_problem
+
+public class CoinChange {
+ // Function to solve the coin change problem
+ public static ArrayList coinChangeProblem(int amount) {
+ // Define an array of coin denominations in descending order
+ Integer coins[] = {1, 2, 5, 10, 20, 50, 100, 500, 2000};
+
+ // Sort the coin denominations in descending order
+ Arrays.sort(coins, Comparator.reverseOrder());
+
+ int count = 0; // Variable to keep track of the total number of coins used
+ ArrayList ans = new ArrayList<>(); // List to store selected coins
+
+ // Iterate through the coin denominations
+ for (int i = 0; i < coins.length; i++) {
+ // Check if the current coin denomination can be used to reduce the remaining amount
+ if (coins[i] <= amount) {
+ // Repeatedly subtract the coin denomination from the remaining amount
+ while (coins[i] <= amount) {
+ count++; // Increment the count of coins used
+ ans.add(coins[i]); // Add the coin to the list of selected coins
+ amount -= coins[i]; // Update the remaining amount
+ }
+ }
+ }
+ return ans;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java b/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java
new file mode 100644
index 000000000000..c5570f35c004
--- /dev/null
+++ b/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java
@@ -0,0 +1,41 @@
+package com.thealgorithms.greedyalgorithms;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+// Problem Link: https://en.wikipedia.org/wiki/Continuous_knapsack_problem
+
+public class FractionalKnapsack {
+ // Function to perform fractional knapsack
+ public static int fractionalKnapsack(int weight[], int value[], int capacity) {
+ // Create a 2D array to store item indices and their value-to-weight ratios.
+ double ratio[][] = new double[weight.length][2];
+
+ // Populate the ratio array with item indices and their value-to-weight ratios.
+ for (int i = 0; i < weight.length; i++) {
+ ratio[i][0] = i; // Assign item index.
+ ratio[i][1] = value[i] / (double) weight[i]; // Calculate and assign value-to-weight ratio.
+ }
+
+ // Sort items by their value-to-weight ratios in descending order.
+ Arrays.sort(ratio, Comparator.comparingDouble(o -> o[1]));
+
+ int finalValue = 0; // Variable to store the final knapsack value.
+ double current = capacity; // Variable to track the remaining capacity of the knapsack.
+
+ // Iterate through the sorted items to select items for the knapsack.
+ for (int i = ratio.length - 1; i >= 0; i--) {
+ int index = (int) ratio[i][0]; // Get the item index.
+ if (current >= weight[index]) {
+ // If the entire item can fit in the knapsack, add its value.
+ finalValue += value[index];
+ current -= weight[index];
+ } else {
+ // If only a fraction of the item can fit, add a proportionate value.
+ finalValue += ratio[i][1] * current;
+ break; // Stop adding items to the knapsack since it's full.
+ }
+ }
+ return finalValue;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java b/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java
new file mode 100644
index 000000000000..bf81e067bac1
--- /dev/null
+++ b/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java
@@ -0,0 +1,65 @@
+package com.thealgorithms.greedyalgorithms;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+
+// Problem Link: https://en.wikipedia.org/wiki/Job-shop_scheduling
+
+public class JobSequencing {
+
+ // Define a Job class that implements Comparable for sorting by profit in descending order
+ static class Job implements Comparable {
+ char id;
+ int deadline;
+ int profit;
+
+ // Compare jobs by profit in descending order
+ @Override
+ public int compareTo(Job otherJob) {
+ return otherJob.profit - this.profit;
+ }
+
+ public Job(char id, int deadline, int profit) {
+ this.id = id;
+ this.deadline = deadline;
+ this.profit = profit;
+ }
+ }
+
+ // Function to print the job sequence
+ public static String findJobSequence(ArrayList jobs, int size) {
+ Boolean[] slots = new Boolean[size];
+ Arrays.fill(slots, false);
+
+ int result[] = new int[size];
+
+ // Iterate through jobs to find the optimal job sequence
+ for (int i = 0; i < size; i++) {
+ for (int j = jobs.get(i).deadline - 1; j >= 0; j--) {
+ if (!slots[j]) {
+ result[j] = i;
+ slots[j] = true;
+ break;
+ }
+ }
+ }
+
+ // Create a StringBuilder to build the job sequence string
+ StringBuilder jobSequenceBuilder = new StringBuilder();
+ jobSequenceBuilder.append("Job Sequence: ");
+ for (int i = 0; i < jobs.size(); i++) {
+ if (slots[i]) {
+ jobSequenceBuilder.append(jobs.get(result[i]).id).append(" -> ");
+ }
+ }
+
+ // Remove the trailing " -> " from the job sequence
+ if (jobSequenceBuilder.length() >= 4) {
+ jobSequenceBuilder.setLength(jobSequenceBuilder.length() - 4);
+ }
+
+ // Return the job sequence as a string
+ return jobSequenceBuilder.toString();
+ }
+}
diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java
new file mode 100644
index 000000000000..42263ac1de8a
--- /dev/null
+++ b/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java
@@ -0,0 +1,42 @@
+package com.thealgorithms.greedyalgorithms;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+
+public class ActivitySelectionTest {
+ @Test
+ public void testActivitySelection() {
+ int start[] = {1, 3, 0, 5, 8, 5};
+ int end[] = {2, 4, 6, 7, 9, 9};
+
+ ArrayList result = ActivitySelection.activitySelection(start, end);
+ ArrayList expected = new ArrayList<>(Arrays.asList(0, 1, 3, 4));
+
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testSingleActivity() {
+ int start[] = {1};
+ int end[] = {2};
+
+ ArrayList result = ActivitySelection.activitySelection(start, end);
+ ArrayList expected = new ArrayList<>(Arrays.asList(0));
+
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testNoOverlap() {
+ int start[] = {1, 2, 3};
+ int end[] = {2, 3, 4};
+
+ ArrayList result = ActivitySelection.activitySelection(start, end);
+ ArrayList expected = new ArrayList<>(Arrays.asList(0, 1, 2));
+
+ assertEquals(expected, result);
+ }
+}
diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java
new file mode 100644
index 000000000000..e9d267712a05
--- /dev/null
+++ b/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java
@@ -0,0 +1,58 @@
+package com.thealgorithms.greedyalgorithms;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+
+public class CoinChangeTest {
+ @Test
+ public void testCoinChangeProblemWithValidAmount() {
+ ArrayList expected = new ArrayList<>(Arrays.asList(500, 50, 20, 20, 1));
+ ArrayList coins = CoinChange.coinChangeProblem(591);
+ assertEquals(expected, coins);
+ }
+
+ @Test
+ public void testCoinChangeProblemWithLargeAmount() {
+ ArrayList expected = new ArrayList<>(Arrays.asList(2000));
+ ArrayList coins = CoinChange.coinChangeProblem(2000);
+ assertEquals(expected, coins);
+ }
+
+ @Test
+ public void testCoinChangeProblemWithPartialCoins2() {
+ ArrayList expected = new ArrayList<>(Arrays.asList(500, 50, 20));
+ ArrayList coins = CoinChange.coinChangeProblem(570);
+ assertEquals(expected, coins);
+ }
+
+ @Test
+ public void testCoinChangeProblemWithSmallAmount() {
+ ArrayList expected = new ArrayList<>(Arrays.asList(2, 1));
+ ArrayList coins = CoinChange.coinChangeProblem(3);
+ assertEquals(expected, coins);
+ }
+
+ @Test
+ public void testCoinChangeProblemWithLargeAmountAndMultipleDenominations() {
+ ArrayList expected = new ArrayList<>(Arrays.asList(2000, 2000, 2000, 2000, 500, 500, 500, 100, 100, 100, 100, 50, 20, 20, 5, 2, 2));
+ ArrayList coins = CoinChange.coinChangeProblem(9999);
+ assertEquals(expected, coins);
+ }
+
+ @Test
+ public void testCoinChangeProblemWithAllDenominations() {
+ ArrayList expected = new ArrayList<>(Arrays.asList(2000, 500, 100, 100, 100, 50, 20, 10, 5, 2, 1));
+ ArrayList coins = CoinChange.coinChangeProblem(2888);
+ assertEquals(expected, coins);
+ }
+
+ @Test
+ public void testCoinChangeProblemWithZeroAmount() {
+ ArrayList expected = new ArrayList<>();
+ ArrayList coins = CoinChange.coinChangeProblem(0);
+ assertEquals(expected, coins);
+ }
+}
diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java
new file mode 100644
index 000000000000..edbf0a09bcbd
--- /dev/null
+++ b/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java
@@ -0,0 +1,32 @@
+package com.thealgorithms.greedyalgorithms;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class FractionalKnapsackTest {
+
+ @Test
+ public void testFractionalKnapsackWithExampleCase() {
+ int weight[] = {10, 20, 30};
+ int value[] = {60, 100, 120};
+ int capacity = 50;
+ assertEquals(240, FractionalKnapsack.fractionalKnapsack(weight, value, capacity));
+ }
+
+ @Test
+ public void testFractionalKnapsackWithZeroCapacity() {
+ int weight[] = {10, 20, 30};
+ int value[] = {60, 100, 120};
+ int capacity = 0;
+ assertEquals(0, FractionalKnapsack.fractionalKnapsack(weight, value, capacity));
+ }
+
+ @Test
+ public void testFractionalKnapsackWithEmptyItems() {
+ int weight[] = {};
+ int value[] = {};
+ int capacity = 50;
+ assertEquals(0, FractionalKnapsack.fractionalKnapsack(weight, value, capacity));
+ }
+}
diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java
new file mode 100644
index 000000000000..8dd42bc7c5ec
--- /dev/null
+++ b/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java
@@ -0,0 +1,23 @@
+package com.thealgorithms.greedyalgorithms;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import org.junit.jupiter.api.Test;
+
+public class JobSequencingTest {
+ @Test
+ public void testJobSequencingWithExampleCase() {
+ ArrayList jobs = new ArrayList<>();
+ jobs.add(new JobSequencing.Job('a', 2, 100));
+ jobs.add(new JobSequencing.Job('b', 1, 19));
+ jobs.add(new JobSequencing.Job('c', 2, 27));
+ jobs.add(new JobSequencing.Job('d', 1, 25));
+ jobs.add(new JobSequencing.Job('e', 3, 15));
+ Collections.sort(jobs);
+ String jobSequence = JobSequencing.findJobSequence(jobs, jobs.size());
+
+ assertEquals("Job Sequence: c -> a -> e", jobSequence);
+ }
+}
From 4fab7adfaa3679d8b41360d169b40ee18b9ed735 Mon Sep 17 00:00:00 2001
From: Arin <136636751+asapekia@users.noreply.github.com>
Date: Tue, 3 Oct 2023 23:02:59 +0530
Subject: [PATCH 0036/1151] code-clean-up (#4519)
* code-clean-up
* style: make `RabinKarpAlgorithm` a proper utility class
---------
Co-authored-by: arintripathi1
Co-authored-by: vil02
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../searches/RabinKarpAlgorithm.java | 67 +++++++++----------
.../searches/RabinKarpAlgorithmTest.java | 3 +-
2 files changed, 33 insertions(+), 37 deletions(-)
diff --git a/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java b/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java
index 8343310d18bf..e774546423f4 100644
--- a/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java
+++ b/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java
@@ -1,50 +1,48 @@
package com.thealgorithms.searches;
-// Following program is a Java implementation
-// of Rabin Karp Algorithm given in the CLRS book
+// Implementation of Rabin Karp Algorithm
-public class RabinKarpAlgorithm {
+public final class RabinKarpAlgorithm {
+ private RabinKarpAlgorithm() {
+ }
// d is the number of characters in the input alphabet
- public static final int d = 256;
+ private static final int d = 256;
+
+ public static int search(String pattern, String text, int primeNumber) {
- /* pat -> pattern
- txt -> text
- q -> A prime number
- */
- public int search(String pat, String txt, int q) {
- int index = -1; // note: -1 here represent not found, it is not an index
- int M = pat.length();
- int N = txt.length();
- int i, j;
- int p = 0; // hash value for pattern
- int t = 0; // hash value for txt
+ int index = -1; // -1 here represents not found
+ int patternLength = pattern.length();
+ int textLength = text.length();
+ int hashForPattern = 0;
+ int hashForText = 0;
int h = 1;
- // The value of h would be "pow(d, M-1)%q"
- for (i = 0; i < M - 1; i++) h = (h * d) % q;
+ // The value of h would be "pow(d, patternLength-1)%primeNumber"
+ for (int i = 0; i < patternLength - 1; i++) h = (h * d) % primeNumber;
// Calculate the hash value of pattern and first
// window of text
- for (i = 0; i < M; i++) {
- p = (d * p + pat.charAt(i)) % q;
- t = (d * t + txt.charAt(i)) % q;
+ for (int i = 0; i < patternLength; i++) {
+ hashForPattern = (d * hashForPattern + pattern.charAt(i)) % primeNumber;
+ hashForText = (d * hashForText + text.charAt(i)) % primeNumber;
}
// Slide the pattern over text one by one
- for (i = 0; i <= N - M; i++) {
- // Check the hash values of current window of text
- // and pattern. If the hash values match then only
- // check for characters one by one
- if (p == t) {
+ for (int i = 0; i <= textLength - patternLength; i++) {
+ /* Check the hash values of current window of text
+ and pattern. If the hash values match then only
+ check for characters one by one*/
+
+ int j = 0;
+ if (hashForPattern == hashForText) {
/* Check for characters one by one */
- for (j = 0; j < M; j++) {
- if (txt.charAt(i + j) != pat.charAt(j)) break;
+ for (j = 0; j < patternLength; j++) {
+ if (text.charAt(i + j) != pattern.charAt(j)) break;
}
- // if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1]
- if (j == M) {
- System.out.println("Pattern found at index " + i);
+ // if hashForPattern == hashForText and pattern[0...patternLength-1] = text[i, i+1, ...i+patternLength-1]
+ if (j == patternLength) {
index = i;
return index;
}
@@ -52,12 +50,11 @@ public int search(String pat, String txt, int q) {
// Calculate hash value for next window of text: Remove
// leading digit, add trailing digit
- if (i < N - M) {
- t = (d * (t - txt.charAt(i) * h) + txt.charAt(i + M)) % q;
+ if (i < textLength - patternLength) {
+ hashForText = (d * (hashForText - text.charAt(i) * h) + text.charAt(i + patternLength)) % primeNumber;
- // We might get negative value of t, converting it
- // to positive
- if (t < 0) t = (t + q);
+ // handling negative hashForText
+ if (hashForText < 0) hashForText = (hashForText + primeNumber);
}
}
return index; // return -1 if pattern does not found
diff --git a/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java b/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java
index 4689dccf08fd..a8dc96e91998 100644
--- a/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java
+++ b/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java
@@ -6,12 +6,11 @@
import org.junit.jupiter.params.provider.CsvSource;
class RabinKarpAlgorithmTest {
- RabinKarpAlgorithm RKA = new RabinKarpAlgorithm();
@ParameterizedTest
@CsvSource({"This is an example for rabin karp algorithmn, algorithmn, 101", "AAABBDDG, AAA, 137", "AAABBCCBB, BBCC, 101", "AAABBCCBB, BBCC, 131", "AAAABBBBCCC, CCC, 41", "ABCBCBCAAB, AADB, 293", "Algorithm The Algorithm, Algorithm, 101"})
void RabinKarpAlgorithmTestExample(String txt, String pat, int q) {
- int indexFromOurAlgorithm = RKA.search(pat, txt, q);
+ int indexFromOurAlgorithm = RabinKarpAlgorithm.search(pat, txt, q);
int indexFromLinearSearch = txt.indexOf(pat);
assertEquals(indexFromOurAlgorithm, indexFromLinearSearch);
}
From a3a2d845d563a901946e052eeebba2f6e51e37d8 Mon Sep 17 00:00:00 2001
From: Appari Satya Barghav <36763910+satyabarghav@users.noreply.github.com>
Date: Wed, 4 Oct 2023 20:02:49 +0530
Subject: [PATCH 0037/1151] Made changes to the code to correct the Logic of
Armstrong Number (#4619)
* Made changes to the code to correct the Logic of Armstrong Number
* Resolved the issues
* Trying to resolve the Linter error by changing Variable name
* Changed Variable Names : trying to resolve Clang error
---
.../com/thealgorithms/maths/Armstrong.java | 33 +++++++++++--------
.../thealgorithms/maths/ArmstrongTest.java | 8 +++--
2 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/Armstrong.java b/src/main/java/com/thealgorithms/maths/Armstrong.java
index dda8288a722f..526b31c3891f 100644
--- a/src/main/java/com/thealgorithms/maths/Armstrong.java
+++ b/src/main/java/com/thealgorithms/maths/Armstrong.java
@@ -1,29 +1,36 @@
package com.thealgorithms.maths;
/**
- * An Armstrong number is equal to the sum of the cubes of its digits. For
- * example, 370 is an Armstrong number because 3*3*3 + 7*7*7 + 0*0*0 = 370. An
- * Armstrong number is often called Narcissistic number.
+ * This class checks whether a given number is an Armstrong number or not.
+ * An Armstrong number is a number that is equal to the sum of its own digits,
+ * each raised to the power of the number of digits.
*
- * @author Vivek
+ * For example, 370 is an Armstrong number because 3^3 + 7^3 + 0^3 = 370.
+ * 1634 is an Armstrong number because 1^4 + 6^4 + 3^4 + 4^4 = 1634.
+ * An Armstrong number is often called a Narcissistic number.
+ *
+ * @author satyabarghav
*/
public class Armstrong {
/**
- * Checks whether a given number is an armstrong number or not.
+ * Checks whether a given number is an Armstrong number or not.
*
- * @param number number to check
- * @return {@code true} if given number is armstrong number, {@code false}
- * otherwise
+ * @param number the number to check
+ * @return {@code true} if the given number is an Armstrong number, {@code false} otherwise
*/
public boolean isArmstrong(int number) {
long sum = 0;
- long number2 = number;
- while (number2 > 0) {
- long mod = number2 % 10;
- sum += Math.pow(mod, 3);
- number2 /= 10;
+ String temp = Integer.toString(number); // Convert the given number to a string
+ int power = temp.length(); // Extract the length of the number (number of digits)
+ long originalNumber = number;
+
+ while (originalNumber > 0) {
+ long digit = originalNumber % 10;
+ sum += Math.pow(digit, power); // The digit raised to the power of the number of digits and added to the sum.
+ originalNumber /= 10;
}
+
return sum == number;
}
}
diff --git a/src/test/java/com/thealgorithms/maths/ArmstrongTest.java b/src/test/java/com/thealgorithms/maths/ArmstrongTest.java
index 3b11b83de75f..e5d0d9eb3c43 100644
--- a/src/test/java/com/thealgorithms/maths/ArmstrongTest.java
+++ b/src/test/java/com/thealgorithms/maths/ArmstrongTest.java
@@ -5,8 +5,8 @@
import org.junit.jupiter.api.Test;
/**
- * @author Vivek
- * @since 15/03/22
+ * @author satyabarghav
+ * @since 4/10/2023
*/
class ArmstrongTest {
@@ -17,7 +17,9 @@ void testIsArmstrong() {
assertThat(armstrong.isArmstrong(1)).isTrue();
assertThat(armstrong.isArmstrong(153)).isTrue();
assertThat(armstrong.isArmstrong(371)).isTrue();
- assertThat(armstrong.isArmstrong(1634)).isFalse();
+ assertThat(armstrong.isArmstrong(1634)).isTrue();
assertThat(armstrong.isArmstrong(200)).isFalse();
+ assertThat(armstrong.isArmstrong(548834)).isTrue();
+ assertThat(armstrong.isArmstrong(9474)).isTrue();
}
}
From 06d6e2116bb1dd825262d6ca447f07eff1dca68d Mon Sep 17 00:00:00 2001
From: Aman <84791435+Aman28801@users.noreply.github.com>
Date: Thu, 5 Oct 2023 18:38:28 +0530
Subject: [PATCH 0038/1151] Update Readme.md (#4634)
---
.../datastructures/graphs/README.md | 78 ++++++++++---------
1 file changed, 42 insertions(+), 36 deletions(-)
diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/README.md b/src/main/java/com/thealgorithms/datastructures/graphs/README.md
index 25e951ad9159..057adb46acf5 100644
--- a/src/main/java/com/thealgorithms/datastructures/graphs/README.md
+++ b/src/main/java/com/thealgorithms/datastructures/graphs/README.md
@@ -1,6 +1,5 @@
-## Graph
-
-Graph is a useful data structure for representing most of the real world problems involving a set of users/candidates/nodes and their relations. A Graph consists of two parameters :
+## Graphs
+Graph is a useful data structure for representing most of the real-world problems involving a set of users/candidates/nodes and their relations. A graph consists of two parameters:
```
V = a set of vertices
@@ -9,59 +8,65 @@ E = a set of edges
Each edge in `E` connects any two vertices from `V`. Based on the type of edge, graphs can be of two types:
-1. **Directed**: The edges are directed in nature which means that when there is an edge from node `A` to `B`, it does not imply that there is an edge from `B` to `A`.
-An example of directed edge graph the **follow** feature of social media. If you follow a celebrity, it doesn't imply that s/he follows you.
+1. **Directed**: The edges are directed in nature, which means that when there is an edge from node `A` to `B`, it does not imply that there is an edge from `B` to `A`. An example of a directed edge graph is the **follow** feature of social media. If you follow a celebrity, it doesn't imply that they follow you.
-2. **Undirected**: The edges don't have any direction. So if `A` and `B` are connected, we can assume that there is edge from both `A` to `B` and `B` to `A`.
-Example: Social media graph, where if two persons are friend, it implies that both are friend with each other.
+2. **Undirected**: The edges don't have any direction. So if `A` and `B` are connected, we can assume that there is an edge from both `A` to `B` and `B` to `A`. For example, in a social media graph, if two persons are friends, it implies that both are friends with each other.
### Components of a Graph
**Vertices:** Vertices are the fundamental units of the graph. Sometimes, vertices are also known as vertex or nodes. Every node/vertex can be labeled or unlabelled.
-**Edges:** Edges are drawn or used to connect two nodes of the graph. It can be ordered pair of nodes in a directed graph. Edges can connect any two nodes in any possible way. There are no rules. Sometimes, edges are also known as arcs. Every edge can be labeled/unlabelled.
-Graphs are used to solve many real-life problems. Graphs are used to represent networks. The networks may include paths in a city or telephone network or circuit network. Graphs are also used in social networks like linkedIn, Facebook. For example, in Facebook, each person is represented with a vertex(or node). Each node is a structure and contains information like person id, name, gender, locale etc.
+**Edges:** Edges are used to connect two nodes of the graph. They can be an ordered pair of nodes in a directed graph. Edges can connect any two nodes in any possible way. There are no rules. Sometimes, edges are also known as arcs. Every edge can be labeled/unlabeled.
+
+Graphs are used to solve many real-life problems. Graphs are used to represent networks. The networks may include paths in a city, telephone network, or circuit network. Graphs are also used in social networks like LinkedIn, Facebook. For example, on Facebook, each person is represented with a vertex (or node). Each node is a structure and contains information like person id, name, gender, locale, etc.
-### Graph Representation:
+### Graph Representation
Graph can be represented in the following ways:
**Set Representation:** Set representation of a graph involves two sets: Set of vertices V = {V1, V2, V3, V4} and set of edges E = {{V1, V2}, {V2, V3}, {V3, V4}, {V4, V1}}. This representation is efficient for memory but does not allow parallel edges.
-**Sequential Representation:** This representation of a graph can be represented by means of matrices: Adjacency Matrix, Incidence matrix and Path matrix.
-**Adjacency Matrix:** This matrix includes information about the adjacent nodes. Here, aij = 1 if there is an edge from Vi to Vj otherwise 0. It is a matrix of order V×V.
-**Incidence Matrix:** This matrix includes information about the incidence of edges on the nodes. Here, aij = 1 if the jth edge Ej is incident on ith vertex Vi otherwise 0. It is a matrix of order V×E.
-**Path Matrix:** This matrix includes information about the simple path between two vertices. Here, Pij = 1 if there is a path from Vi to Vj otherwise 0. It is also called as reachability matrix of graph G.
-**Linked Representation:** This representation gives the information about the nodes to which a specific node is connected i.e. adjacency lists. This representation gives the adjacency lists of the vertices with the help of array and linked lists. In the adjacency lists, the vertices which are connected with the specific vertex are arranged in the form of lists which is connected to that vertex.
+**Sequential Representation:** This representation of a graph can be represented by means of matrices: Adjacency Matrix, Incidence matrix, and Path matrix.
+
+**Adjacency Matrix:** This matrix includes information about the adjacent nodes. Here, aij = 1 if there is an edge from Vi to Vj; otherwise, it's 0. It is a matrix of order V×V.
+
+**Incidence Matrix:** This matrix includes information about the incidence of edges on the nodes. Here, aij = 1 if the jth edge Ej is incident on the ith vertex Vi; otherwise, it's 0. It is a matrix of order V×E.
+
+**Path Matrix:** This matrix includes information about the simple path between two vertices. Here, Pij = 1 if there is a path from Vi to Vj; otherwise, it's 0. It is also called the reachability matrix of graph G.
+
+**Linked Representation:** This representation gives information about the nodes to which a specific node is connected, i.e., adjacency lists. This representation gives the adjacency lists of the vertices with the help of arrays and linked lists. In the adjacency lists, the vertices connected to the specific vertex are arranged in the form of lists that are connected to that vertex.
-### Real-Time Applications of Graph:
-Graphs are used to represent flow of control in computers.
-Graphs are used in social networking sites where users act as nodes and connection between them acts as edges.
+### Real-Time Applications of Graph
+
+Graphs are used to represent the flow of control in computers.
+Graphs are used in social networking sites where users act as nodes, and connections between them act as edges.
In an operating system, graphs are used as resource allocation graphs.
-Graphs are used in Google maps to find the shortest route.
-Graphs are also used in airlines system for effective route optimization.
-In-state transition diagrams, the graph is used to represent their states and their transition.
+Graphs are used in Google Maps to find the shortest route.
+Graphs are also used in the airline system for effective route optimization.
+In state transition diagrams, the graph is used to represent states and their transitions.
In transportation, graphs are used to find the shortest path.
In circuits, graphs can be used to represent circuit points as nodes and wires as edges.
Graphs are used in solving puzzles with only one solution, such as mazes.
-Graphs are used in computer networks for Peer to peer (P2P) applications.
-Graphs basically in the form of DAG(Directed acyclic graph) are used as alternative to blockchain for cryptocurrency. For example crypto like IOTA, Nano are mainly based on DAG.
+Graphs are used in computer networks for Peer to Peer (P2P) applications.
+Graphs, basically in the form of DAG (Directed Acyclic Graph), are used as an alternative to blockchain for cryptocurrency. For example, cryptocurrencies like IOTA and Nano are mainly based on DAG.
+
+### Advantages of Graph
-### Advantages of Graph:
-By using graphs we can easily find the shortest path, neighbors of the nodes, and many more.
+Using graphs, we can easily find the shortest path, neighbors of the nodes, and many more.
Graphs are used to implement algorithms like DFS and BFS.
-It is used to find minimum spanning tree which has many practical applications.
-It helps in organizing data.
-Because of its non-linear structure, helps in understanding complex problems and their visualization.
+They are used to find minimum spanning trees, which have many practical applications.
+Graphs help in organizing data.
+Because of their non-linear structure, graphs help in understanding complex problems and their visualization.
+
+### Disadvantages of Graph
-### Disadvantages of Graph:
-Graphs use lots of pointers which can be complex to handle.
-It can have large memory complexity.
-If the graph is represented with an adjacency matrix then it does not allow parallel edges and multiplication of the graph is also difficult.
+Graphs use lots of pointers, which can be complex to handle.
+They can have large memory complexity.
+If the graph is represented with an adjacency matrix, then it does not allow parallel edges, and multiplication of the graph is also difficult.
### Representation
-1. **Adjacency Lists**: Each node is represented as an entry and all the edges are represented as a list emerging from the corresponding node. So if vertex `1` has eadges to 2,3, and 6, the list corresponding to 1 will have 2,3 and 6 as entries. Consider the following graph.
+1. **Adjacency Lists**: Each node is represented as an entry, and all the edges are represented as a list emerging from the corresponding node. So, if vertex 1 has edges to 2, 3, and 6, the list corresponding to 1 will have 2, 3, and 6 as entries. Consider the following graph:
```
0: 1-->2-->3
@@ -70,9 +75,10 @@ If the graph is represented with an adjacency matrix then it does not allow para
3: 0-->4
4: 3
```
-It means there are edges from 0 to 1, 2 and 3; from 1 to 0 and 2 and so on.
-2. **Adjacency Matrix**: The graph is represented as a matrix of size `|V| x |V|` and an entry 1 in cell `(i,j)` implies that there is an edge from i to j. 0 represents no edge.
-The mtrix for the above graph:
+
+It means there are edges from 0 to 1, 2, and 3; from 1 to 0 and 2, and so on.
+
+2. **Adjacency Matrix**: The graph is represented as a matrix of size |V| x |V|, and an entry 1 in cell (i, j) implies that there is an edge from i to j. 0 represents no edge. The matrix for the above graph:
```
0 1 2 3 4
From 064ca8f59124eb3c792d2202ff12260e87e91552 Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Thu, 5 Oct 2023 22:01:27 +0200
Subject: [PATCH 0039/1151] cleanup `FindMinRecursion` (#4568)
* Create FindMinRecusionTest.java
* Update FindMinRecursion.java
* Update FindMinRecursion.java
* Update FindMinRecursion.java
* Rename FindMinRecusionTest.java to FindMinRecursionTest.java
* Update FindMinRecursionTest.java
* style: remove unused imports
---------
Co-authored-by: vil02 <65706193+vil02@users.noreply.github.com>
---
.../thealgorithms/maths/FindMinRecursion.java | 41 ++++---------------
.../maths/FindMinRecursionTest.java | 28 +++++++++++++
2 files changed, 36 insertions(+), 33 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java
diff --git a/src/main/java/com/thealgorithms/maths/FindMinRecursion.java b/src/main/java/com/thealgorithms/maths/FindMinRecursion.java
index 71d7795b7e47..6ffe034ee40f 100644
--- a/src/main/java/com/thealgorithms/maths/FindMinRecursion.java
+++ b/src/main/java/com/thealgorithms/maths/FindMinRecursion.java
@@ -1,38 +1,13 @@
package com.thealgorithms.maths;
-import java.util.Arrays;
-import java.util.Random;
+public final class FindMinRecursion {
-public class FindMinRecursion {
-
- /**
- * Driver Code
- */
- public static void main(String[] args) {
- Random rand = new Random();
-
- /* rand size */
- int size = rand.nextInt(100) + 1;
- int[] array = new int[size];
-
- /* init array with rand numbers */
- for (int i = 0; i < size; i++) {
- array[i] = rand.nextInt() % 100;
- }
-
- assert min(array, 0, array.length - 1) == Arrays.stream(array).min().getAsInt();
- assert min(array) == Arrays.stream(array).min().getAsInt();
+ private FindMinRecursion() {
}
-
- /**
- * Get min of array using divide and conquer algorithm
- *
- * @param array contains elements
- * @param low the index of the first element
- * @param high the index of the last element
- * @return min of {@code array}
- */
- public static int min(int[] array, int low, int high) {
+ public static int min(final int[] array, final int low, final int high) {
+ if (array.length == 0) {
+ throw new IllegalArgumentException("array must be non-empty.");
+ }
if (low == high) {
return array[low]; // or array[high]
}
@@ -52,7 +27,7 @@ public static int min(int[] array, int low, int high) {
* @param len length of given array
* @return min value of {@code array}
*/
- public static int min(int[] array) {
- return array.length == 1 ? array[0] : min(array, 0, array.length);
+ public static int min(final int[] array) {
+ return min(array, 0, array.length - 1);
}
}
diff --git a/src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java b/src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java
new file mode 100644
index 000000000000..3c36702b881d
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java
@@ -0,0 +1,28 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class FindMinRecursionTest {
+
+ @ParameterizedTest
+ @MethodSource("inputStream")
+ void numberTests(int expected, int[] input) {
+ Assertions.assertEquals(expected, FindMinRecursion.min(input));
+ }
+
+ private static Stream inputStream() {
+ return Stream.of(Arguments.of(5, new int[] {5, 5, 5, 5, 5}), Arguments.of(-1, new int[] {-1, 0}), Arguments.of(-10, new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}), Arguments.of(-4, new int[] {3, -2, 3, 9, -4, -4, 8}), Arguments.of(3, new int[] {3}));
+ }
+
+ @Test
+ public void testFindMaxThrowsExceptionForEmptyInput() {
+ assertThrows(IllegalArgumentException.class, () -> FindMinRecursion.min(new int[] {}));
+ }
+}
From 081f308b9d7c2a22935eff6f8b7b18258111a3d3 Mon Sep 17 00:00:00 2001
From: Suchi Bansal
Date: Fri, 6 Oct 2023 23:45:27 +0530
Subject: [PATCH 0040/1151] Add `ReverseWordsInString` (#4456)
* return a string of the words in reverse order concatenated by a single space.
Input: s = "the sky is blue"
Output: "blue is sky the"
* return a string of the words in reverse order concatenated by a single space.
Input: s = "the sky is blue"
Output: "blue is sky the"
* space reduce
* removed main method
* added test cases
* formatting fix
* formatting fix
* worked on pr reviews
* formatting fix
* private constructor added
* added test case for when string contains white space
* simplified method
* fix issue
* formatting issues fix
* fixed issue
* code refactor
* documented method
* worked on pr comments
* docs: add missing space
* tests: express as `ParameterizedTest`
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Co-authored-by: vil02
---
.../strings/ReverseWordsInString.java | 22 +++++++++++++++++++
.../strings/ReverseWordsInStringTest.java | 20 +++++++++++++++++
2 files changed, 42 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/strings/ReverseWordsInString.java
create mode 100644 src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java
diff --git a/src/main/java/com/thealgorithms/strings/ReverseWordsInString.java b/src/main/java/com/thealgorithms/strings/ReverseWordsInString.java
new file mode 100644
index 000000000000..5f9d27b4e9e2
--- /dev/null
+++ b/src/main/java/com/thealgorithms/strings/ReverseWordsInString.java
@@ -0,0 +1,22 @@
+package com.thealgorithms.strings;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public final class ReverseWordsInString {
+
+ private ReverseWordsInString() {
+ }
+
+ /**
+ * @brief Reverses words in the input string
+ * @param s the input string
+ * @return A string created by reversing the order of the words in {@code s}
+ */
+
+ public static String reverseWordsInString(final String s) {
+ var words = s.trim().split("\\s+");
+ Collections.reverse(Arrays.asList(words));
+ return String.join(" ", words);
+ }
+}
diff --git a/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java b/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java
new file mode 100644
index 000000000000..44e397459349
--- /dev/null
+++ b/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java
@@ -0,0 +1,20 @@
+package com.thealgorithms.strings;
+
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class ReverseWordsInStringTest {
+ @ParameterizedTest
+ @MethodSource("inputStream")
+ void numberTests(String expected, String input) {
+ Assertions.assertEquals(expected, ReverseWordsInString.reverseWordsInString(input));
+ }
+
+ private static Stream inputStream() {
+ return Stream.of(Arguments.of("blue is Sky", "Sky is blue"), Arguments.of("blue is Sky", "Sky \n is \t \n blue "), Arguments.of("", ""), Arguments.of("", " "), Arguments.of("", "\t"));
+ }
+}
From aaa2b26ed19477c4e8b8198782c1ee6c560bf8b3 Mon Sep 17 00:00:00 2001
From: Piyush Pagar <89297062+PiyushPagar@users.noreply.github.com>
Date: Sat, 7 Oct 2023 18:57:46 +0530
Subject: [PATCH 0041/1151] Issue #4706 Solved (#4707)
Import Package into the RecursiveBinarySearchTest and RecursiveBinarySearch
Co-authored-by: PiyushPagar1
---
.../java/com/thealgorithms/searches/RecursiveBinarySearch.java | 2 +-
.../com/thealgorithms/searches/RecursiveBinarySearchTest.java | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java b/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java
index 8a02b30a9f0e..0a84aa1d64ce 100644
--- a/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java
+++ b/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java
@@ -2,7 +2,7 @@
// Created:- 1/10/2023
// File Name should be RecursiveBinarySearch.java
// Explanation:- https://www.tutorialspoint.com/java-program-for-binary-search-recursive
-
+package com.thealgorithms.searches;
import java.util.*;
// Create a SearchAlgorithm class with a generic type
diff --git a/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java b/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java
index 3b2cdead1c6b..4144efa5e89b 100644
--- a/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java
+++ b/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java
@@ -1,6 +1,7 @@
// Created by Pronay Debnath
// Date:- 1/10/2023
// Test file updated with JUnit tests
+package com.thealgorithms.searches;
import static org.junit.jupiter.api.Assertions.*;
From 7f9555bd947fcb2292514642655810dd59d02c87 Mon Sep 17 00:00:00 2001
From: Anuj Rathour
Date: Sat, 7 Oct 2023 23:07:57 +0530
Subject: [PATCH 0042/1151] Update stack readme.md (#4678)
---
.../datastructures/stacks/README.md | 20 ++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/README.md b/src/main/java/com/thealgorithms/datastructures/stacks/README.md
index 69fc3a990383..55c3ffd7de64 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/README.md
+++ b/src/main/java/com/thealgorithms/datastructures/stacks/README.md
@@ -1,10 +1,14 @@
# STACK
-Stack is an ADT (abstract data type) that acts like a list of objects but there is a difference.
+- Stack is an ADT (abstract data type) that is a collection of elements where items are added and removed from the end, known as the "top" of the stack.
-Stack works on the principle of _LIFO_ (Last In First Out), it means that the last item added to the stack will be the first item to be removed.
+- Stack works on the principle of _LIFO_ (Last In First Out), it means that the last item added to the stack will be the first item to be removed.
-Stack is based on two methods (functions)-
+## Declaration
+ `Stack stack=new Stack();`
+
+# Functionalities
+Stack is based on two functions (methods)-
## push(element)
@@ -29,3 +33,13 @@ It removes the last element (i.e. top of stack) from stack.
For example: If we have `1, 3, 5 , 9` in stack, and we call pop(),
the function will return `9` and the stack will change to `1, 3, 5`.
+
+# Real Life Applications
+ - `Undo mechanisms:`
+ Many software applications use stacks to implement an "undo" feature.
+
+ - `Browser history:`
+ The "back" button in a web browser is implemented using a stack, allowing users to navigate through previously visited pages.
+
+ - `Function calls and recursion:`
+ The computer's call stack keeps track of function calls, allowing programs to remember where to return after a function finishes execution.
From 06aa834fa6991a15e36ef0ca4c44f4522cbdb347 Mon Sep 17 00:00:00 2001
From: Aman <84791435+Aman28801@users.noreply.github.com>
Date: Sun, 8 Oct 2023 13:17:35 +0530
Subject: [PATCH 0043/1151] Enhance queue README.md (#4710)
---
.../datastructures/queues/README.md | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/src/main/java/com/thealgorithms/datastructures/queues/README.md b/src/main/java/com/thealgorithms/datastructures/queues/README.md
index e110686acae9..ca5e2972f8c5 100644
--- a/src/main/java/com/thealgorithms/datastructures/queues/README.md
+++ b/src/main/java/com/thealgorithms/datastructures/queues/README.md
@@ -7,6 +7,29 @@
- It supports all methods of Collection interface including insertion, deletion etc.
- LinkedList, ArrayBlockingQueue and PriorityQueue are the most commonly used implementations.
+
+## Types Of Queue:-
+
+- **FIFO Queue (First-In-First-Out):** This is the most common type of queue where the first item added is the first one to be removed. It follows a strict order of insertion and removal.
+
+
+- **Priority Queue:** Elements in this queue are assigned priorities, and the item with the highest priority is dequeued first. It doesn't strictly follow the FIFO order.
+
+
+- **Double-ended Queue (Deque):** A queue that allows elements to be added and removed from both ends. It can function as both a FIFO queue and a LIFO stack.
+
+
+- **Circular Queue:** In this type, the last element is connected to the first element, forming a circular structure. It's often used for tasks like managing memory buffers.
+
+
+- **Blocking Queue:** Designed for multithreaded applications, it provides thread-safety and blocking operations. Threads can wait until an element is available or space is free.
+
+
+- **Priority Blocking Queue:** Similar to a priority queue but thread-safe, it allows multiple threads to access and modify the queue concurrently while maintaining priority.
+
+
+- **Delay Queue:** Used for scheduling tasks to run after a specific delay or at a certain time. Elements are removed from the queue when their delay expires.
+
## Declaration
`Queue queue = new PriorityQueue ();`
@@ -21,3 +44,5 @@
|Rear|Gets the last item from the queue|
+
+
From 8200a791a28002ca23ac70c73d4c83399beab831 Mon Sep 17 00:00:00 2001
From: Prabhat-Kumar
Date: Sun, 8 Oct 2023 18:46:06 +0530
Subject: [PATCH 0044/1151] Add `AhoCorasick` (#4465)
* Added code to find Articulation Points and Bridges
* tried to solve clang-formant test
* removed new line at EOF to get lint to pass
* feature: Added Ahocorasick Algorithm
* fixed lint using clang-format
* removed datastructures/graphs/ArticulationPointsAndBridge.java from this branch
* removed main, since test-file is added. Also modified and renamed few functions.
* Added test-file for AhoCorasick Algorithm
* Modified some comments in test-file
* Modified some comments in AhoCorasick.java
* lint fix
* added few more test cases
* Modified some comments
* Change all class fields to private, added initializeSuffixLinksForChildNodesOfTheRoot() method, hashmap string search position (also has previous index based search), removed java.util.*
* Added Missing Test-Cases and more
* minor text changes
* added direct test check i.e. defining a variable expected and just checking if res and expected are equal.
* Created New Class Trie, merged 'buildTrie and buildSuffixAndOutputLinks' with 'Trie constructor'. Merged setUpStartPoints with searchIn. Now AhoCorasick contains -> inner class: Trie, Node. Methods: search and convert. Trie has -> Methods : constructor and searchIn
* Updated TestFile according to the updated AhoCorasick Class. Added Few more test cases
* updated - broken down constructor to relavent parts, made string final, made res local to searchIn(), doxygen-like style
* lint fix clang
* Updated Tests Files
* Added final field to Node class setters and Trie Constructor arguments, removed getTrieRoot() and some unnecessory comments, renamed [old -> new]: res -> positionByStringIndexValue, removed if condition from setupStartPoints()
* updated test file
* lint fix clang
* minor chage - 'removed a comment'
* added final fields to some arguments, class and variables, added a method initializePositionByStringIndexValue()
* updated to remove * inclusion and added the required modules only
* Implemented a new class PatternPositionRecorder to wrap up the position recording in searchIn()
* Added final fields to PatternPositionRecorder Class
* style: mark default constructor of `AhoCorasick` as `private`
* style: remoce redundant `public`
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../thealgorithms/strings/AhoCorasick.java | 249 ++++++++++++++++++
.../strings/AhoCorasickTest.java | 120 +++++++++
2 files changed, 369 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/strings/AhoCorasick.java
create mode 100644 src/test/java/com/thealgorithms/strings/AhoCorasickTest.java
diff --git a/src/main/java/com/thealgorithms/strings/AhoCorasick.java b/src/main/java/com/thealgorithms/strings/AhoCorasick.java
new file mode 100644
index 000000000000..6381830cb0bc
--- /dev/null
+++ b/src/main/java/com/thealgorithms/strings/AhoCorasick.java
@@ -0,0 +1,249 @@
+/*
+ * Aho-Corasick String Matching Algorithm Implementation
+ *
+ * This code implements the Aho-Corasick algorithm, which is used for efficient
+ * string matching in a given text. It can find multiple patterns simultaneously
+ * and records their positions in the text.
+ *
+ * Author: Prabhat-Kumar-42
+ * GitHub: https://github.com/Prabhat-Kumar-42
+ */
+
+package com.thealgorithms.strings;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+
+public final class AhoCorasick {
+ private AhoCorasick() {
+ }
+
+ // Trie Node Class
+ private static class Node {
+ // Represents a character in the trie
+ private HashMap child = new HashMap<>(); // Child nodes of the current node
+ private Node suffixLink; // Suffix link to another node in the trie
+ private Node outputLink; // Output link to another node in the trie
+ private int patternInd; // Index of the pattern that ends at this node
+
+ Node() {
+ this.suffixLink = null;
+ this.outputLink = null;
+ this.patternInd = -1;
+ }
+
+ public HashMap getChild() {
+ return child;
+ }
+
+ public Node getSuffixLink() {
+ return suffixLink;
+ }
+
+ public void setSuffixLink(final Node suffixLink) {
+ this.suffixLink = suffixLink;
+ }
+
+ public Node getOutputLink() {
+ return outputLink;
+ }
+
+ public void setOutputLink(final Node outputLink) {
+ this.outputLink = outputLink;
+ }
+
+ public int getPatternInd() {
+ return patternInd;
+ }
+
+ public void setPatternInd(final int patternInd) {
+ this.patternInd = patternInd;
+ }
+ }
+
+ // Trie Class
+ public static class Trie {
+
+ private Node root = null; // Root node of the trie
+ private final String[] patterns; // patterns according to which Trie is constructed
+
+ public Trie(final String[] patterns) {
+ root = new Node(); // Initialize the root of the trie
+ this.patterns = patterns;
+ buildTrie();
+ buildSuffixAndOutputLinks();
+ }
+
+ // builds AhoCorasick Trie
+ private void buildTrie() {
+
+ // Loop through each input pattern and building Trie
+ for (int i = 0; i < patterns.length; i++) {
+ Node curr = root; // Start at the root of the trie for each pattern
+
+ // Loop through each character in the current pattern
+ for (int j = 0; j < patterns[i].length(); j++) {
+ char c = patterns[i].charAt(j); // Get the current character
+
+ // Check if the current node has a child for the current character
+ if (curr.getChild().containsKey(c)) {
+ curr = curr.getChild().get(c); // Update the current node to the child node
+ } else {
+ // If no child node exists, create a new one and add it to the current node's children
+ Node nn = new Node();
+ curr.getChild().put(c, nn);
+ curr = nn; // Update the current node to the new child node
+ }
+ }
+ curr.setPatternInd(i); // Store the index of the pattern in the current leaf node
+ }
+ }
+
+ private void initializeSuffixLinksForChildNodesOfTheRoot(Queue q) {
+ for (char rc : root.getChild().keySet()) {
+ Node childNode = root.getChild().get(rc);
+ q.add(childNode); // Add child node to the queue
+ childNode.setSuffixLink(root); // Set suffix link to the root
+ }
+ }
+
+ private void buildSuffixAndOutputLinks() {
+ root.setSuffixLink(root); // Initialize the suffix link of the root to itself
+ Queue q = new LinkedList<>(); // Initialize a queue for BFS traversal
+
+ initializeSuffixLinksForChildNodesOfTheRoot(q);
+
+ while (!q.isEmpty()) {
+ Node currentState = q.poll(); // Get the current node for processing
+
+ // Iterate through child nodes of the current node
+ for (char cc : currentState.getChild().keySet()) {
+ Node currentChild = currentState.getChild().get(cc); // Get the child node
+ Node parentSuffix = currentState.getSuffixLink(); // Get the parent's suffix link
+
+ // Calculate the suffix link for the child based on the parent's suffix link
+ while (!parentSuffix.getChild().containsKey(cc) && parentSuffix != root) {
+ parentSuffix = parentSuffix.getSuffixLink();
+ }
+
+ // Set the calculated suffix link or default to root
+ if (parentSuffix.getChild().containsKey(cc)) {
+ currentChild.setSuffixLink(parentSuffix.getChild().get(cc));
+ } else {
+ currentChild.setSuffixLink(root);
+ }
+
+ q.add(currentChild); // Add the child node to the queue for further processing
+ }
+
+ // Establish output links for nodes to efficiently identify patterns within patterns
+ if (currentState.getSuffixLink().getPatternInd() >= 0) {
+ currentState.setOutputLink(currentState.getSuffixLink());
+ } else {
+ currentState.setOutputLink(currentState.getSuffixLink().getOutputLink());
+ }
+ }
+ }
+
+ private ArrayList> initializePositionByStringIndexValue() {
+ ArrayList> positionByStringIndexValue = new ArrayList<>(patterns.length); // Stores positions where patterns are found in the text
+ for (int i = 0; i < patterns.length; i++) {
+ positionByStringIndexValue.add(new ArrayList());
+ }
+ return positionByStringIndexValue;
+ }
+
+ // Searches for patterns in the input text and records their positions
+ public ArrayList> searchIn(final String text) {
+ var positionByStringIndexValue = initializePositionByStringIndexValue(); // Initialize a list to store positions of the current pattern
+ Node parent = root; // Start searching from the root node
+
+ PatternPositionRecorder positionRecorder = new PatternPositionRecorder(positionByStringIndexValue);
+
+ for (int i = 0; i < text.length(); i++) {
+ char ch = text.charAt(i); // Get the current character in the text
+
+ // Check if the current node has a child for the current character
+ if (parent.getChild().containsKey(ch)) {
+ parent = parent.getChild().get(ch); // Update the current node to the child node
+ positionRecorder.recordPatternPositions(parent, i); // Use the method in PatternPositionRecorder to record positions
+ } else {
+ // If no child node exists for the character, backtrack using suffix links
+ while (parent != root && !parent.getChild().containsKey(ch)) {
+ parent = parent.getSuffixLink();
+ }
+ if (parent.getChild().containsKey(ch)) {
+ i--; // Decrement i to reprocess the same character
+ }
+ }
+ }
+
+ setUpStartPoints(positionByStringIndexValue);
+ return positionByStringIndexValue;
+ }
+
+ // by default positionByStringIndexValue contains end-points. This function converts those
+ // endpoints to start points
+ private void setUpStartPoints(ArrayList> positionByStringIndexValue) {
+ for (int i = 0; i < patterns.length; i++) {
+ for (int j = 0; j < positionByStringIndexValue.get(i).size(); j++) {
+ int endpoint = positionByStringIndexValue.get(i).get(j);
+ positionByStringIndexValue.get(i).set(j, endpoint - patterns[i].length() + 1);
+ }
+ }
+ }
+ }
+
+ // Class to handle pattern position recording
+ private static class PatternPositionRecorder {
+ private ArrayList> positionByStringIndexValue;
+
+ // Constructor to initialize the recorder with the position list
+ PatternPositionRecorder(final ArrayList> positionByStringIndexValue) {
+ this.positionByStringIndexValue = positionByStringIndexValue;
+ }
+
+ /**
+ * Records positions for a pattern when it's found in the input text and follows
+ * output links to record positions of other patterns.
+ *
+ * @param parent The current node representing a character in the pattern trie.
+ * @param currentPosition The current position in the input text.
+ */
+ public void recordPatternPositions(final Node parent, final int currentPosition) {
+ // Check if the current node represents the end of a pattern
+ if (parent.getPatternInd() > -1) {
+ // Add the current position to the list of positions for the found pattern
+ positionByStringIndexValue.get(parent.getPatternInd()).add(currentPosition);
+ }
+
+ Node outputLink = parent.getOutputLink();
+ // Follow output links to find and record positions of other patterns
+ while (outputLink != null) {
+ // Add the current position to the list of positions for the pattern linked by outputLink
+ positionByStringIndexValue.get(outputLink.getPatternInd()).add(currentPosition);
+ outputLink = outputLink.getOutputLink();
+ }
+ }
+ }
+ // method to search for patterns in text
+ public static Map> search(final String text, final String[] patterns) {
+ final var trie = new Trie(patterns);
+ final var positionByStringIndexValue = trie.searchIn(text);
+ return convert(positionByStringIndexValue, patterns);
+ }
+
+ // method for converting results to a map
+ private static Map> convert(final ArrayList> positionByStringIndexValue, final String[] patterns) {
+ Map> positionByString = new HashMap<>();
+ for (int i = 0; i < patterns.length; i++) {
+ String pattern = patterns[i];
+ ArrayList positions = positionByStringIndexValue.get(i);
+ positionByString.put(pattern, new ArrayList<>(positions));
+ }
+ return positionByString;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java b/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java
new file mode 100644
index 000000000000..caaca561143f
--- /dev/null
+++ b/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java
@@ -0,0 +1,120 @@
+/*
+ * Tests For Aho-Corasick String Matching Algorithm
+ *
+ * Author: Prabhat-Kumar-42
+ * GitHub: https://github.com/Prabhat-Kumar-42
+ */
+
+package com.thealgorithms.strings;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * This class contains test cases for the Aho-Corasick String Matching Algorithm.
+ * The Aho-Corasick algorithm is used to efficiently find all occurrences of multiple
+ * patterns in a given text.
+ */
+class AhoCorasickTest {
+ private String[] patterns; // The array of patterns to search for
+ private String text; // The input text to search within
+
+ /**
+ * This method sets up the test environment before each test case.
+ * It initializes the patterns and text to be used for testing.
+ */
+ @BeforeEach
+ void setUp() {
+ patterns = new String[] {"ACC", "ATC", "CAT", "GCG", "C", "T"};
+ text = "GCATCG";
+ }
+
+ /**
+ * Test searching for multiple patterns in the input text.
+ * The expected results are defined for each pattern.
+ */
+ @Test
+ void testSearch() {
+ // Define the expected results for each pattern
+ final var expected = Map.of("ACC", new ArrayList<>(Arrays.asList()), "ATC", new ArrayList<>(Arrays.asList(2)), "CAT", new ArrayList<>(Arrays.asList(1)), "GCG", new ArrayList<>(Arrays.asList()), "C", new ArrayList<>(Arrays.asList(1, 4)), "T", new ArrayList<>(Arrays.asList(3)));
+ assertEquals(expected, AhoCorasick.search(text, patterns));
+ }
+
+ /**
+ * Test searching with an empty pattern array.
+ * The result should be an empty map.
+ */
+ @Test
+ void testEmptyPatterns() {
+ // Define an empty pattern array
+ final var emptyPatterns = new String[] {};
+ assertTrue(AhoCorasick.search(text, emptyPatterns).isEmpty());
+ }
+
+ /**
+ * Test searching for patterns that are not present in the input text.
+ * The result should be an empty list for each pattern.
+ */
+ @Test
+ void testPatternNotFound() {
+ // Define patterns that are not present in the text
+ final var searchPatterns = new String[] {"XYZ", "123"};
+ final var expected = Map.of("XYZ", new ArrayList(), "123", new ArrayList());
+ assertEquals(expected, AhoCorasick.search(text, searchPatterns));
+ }
+
+ /**
+ * Test searching for patterns that start at the beginning of the input text.
+ * The expected position for each pattern is 0.
+ */
+ @Test
+ void testPatternAtBeginning() {
+ // Define patterns that start at the beginning of the text
+ final var searchPatterns = new String[] {"GC", "GCA", "GCAT"};
+ final var expected = Map.of("GC", new ArrayList(Arrays.asList(0)), "GCA", new ArrayList(Arrays.asList(0)), "GCAT", new ArrayList(Arrays.asList(0)));
+ assertEquals(expected, AhoCorasick.search(text, searchPatterns));
+ }
+
+ /**
+ * Test searching for patterns that end at the end of the input text.
+ * The expected positions are 4, 3, and 2 for the patterns.
+ */
+ @Test
+ void testPatternAtEnd() {
+ // Define patterns that end at the end of the text
+ final var searchPatterns = new String[] {"CG", "TCG", "ATCG"};
+ final var expected = Map.of("CG", new ArrayList(Arrays.asList(4)), "TCG", new ArrayList(Arrays.asList(3)), "ATCG", new ArrayList(Arrays.asList(2)));
+ assertEquals(expected, AhoCorasick.search(text, searchPatterns));
+ }
+
+ /**
+ * Test searching for patterns with multiple occurrences in the input text.
+ * The expected sizes are 1 and 1, and the expected positions are 2 and 3
+ * for the patterns "AT" and "T" respectively.
+ */
+ @Test
+ void testMultipleOccurrencesOfPattern() {
+ // Define patterns with multiple occurrences in the text
+ final var searchPatterns = new String[] {"AT", "T"};
+ final var expected = Map.of("AT", new ArrayList(Arrays.asList(2)), "T", new ArrayList(Arrays.asList(3)));
+ assertEquals(expected, AhoCorasick.search(text, searchPatterns));
+ }
+
+ /**
+ * Test searching for patterns in a case-insensitive manner.
+ * The search should consider patterns regardless of their case.
+ */
+ @Test
+ void testCaseInsensitiveSearch() {
+ // Define patterns with different cases
+ final var searchPatterns = new String[] {"gca", "aTc", "C"};
+ final var expected = Map.of("gca", new ArrayList(), "aTc", new ArrayList(), "C", new ArrayList(Arrays.asList(1, 4)));
+ assertEquals(expected, AhoCorasick.search(text, searchPatterns));
+ }
+}
From facc62a81afd1ff8a5f9cb3a78e505ee2e6515c1 Mon Sep 17 00:00:00 2001
From: Arin <136636751+asapekia@users.noreply.github.com>
Date: Mon, 9 Oct 2023 00:36:13 +0530
Subject: [PATCH 0045/1151] adding formatting steps in pull request template
(#4606)
* adding formatting steps in contribution.md
* adding format to pull request template
* made format instruction shorter
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.github/pull_request_template.md | 1 +
CONTRIBUTING.md | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index ce1d87a2c62e..d9cc4c3c35c5 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -13,3 +13,4 @@ In order to reduce the number of notifications sent to the maintainers, please:
- [ ] All filenames are in PascalCase.
- [ ] All functions and variable names follow Java naming conventions.
- [ ] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.
+- [ ] All new code is formatted with `clang-format -i --style=file path/to/your/file.java`
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index dcc86c50360d..f2f8dd9ffdea 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -28,4 +28,4 @@ NOTE: *Please avoid opening issues asking to be "assigned" to a particular algor
- Ask any question about how to use the repository in the [TheAlgorithms room in GITTER](https://gitter.im/TheAlgorithms/community?source=orgpage#) or [open a new issue](https://github.com/TheAlgorithms/Java/issues/new)
-:+1::tada: That's all you need to know about the process now it's your turn to help us improve the repository, thank you again! :+1::tada:
+:+1::tada: That's all you need to know about the process now it's your turn to help us improve the repository, thank you again! :+1::tada:
\ No newline at end of file
From c6a22de12f820f3f6f92a60515acce979ff16162 Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Mon, 9 Oct 2023 17:17:02 +0200
Subject: [PATCH 0046/1151] Add `MinValueTest` and remove `main` from
`MinValue` (#4713)
* Update MinValue.java
* Create MinValueTest.java
* Revert "Create MinValueTest.java"
* Create MinValueTest.java
* Update MinValueTest.java
* Update MinValueTest.java
* Update MinValue.java
* Update src/test/java/com/thealgorithms/maths/MinValueTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/maths/MinValueTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/MinValue.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../com/thealgorithms/maths/MinValue.java | 20 ++-----------------
.../com/thealgorithms/maths/MinValueTest.java | 14 +++++++++++++
2 files changed, 16 insertions(+), 18 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/maths/MinValueTest.java
diff --git a/src/main/java/com/thealgorithms/maths/MinValue.java b/src/main/java/com/thealgorithms/maths/MinValue.java
index badc6c7cfb69..88e28e8816c6 100644
--- a/src/main/java/com/thealgorithms/maths/MinValue.java
+++ b/src/main/java/com/thealgorithms/maths/MinValue.java
@@ -1,24 +1,8 @@
package com.thealgorithms.maths;
-import java.util.Random;
-
-public class MinValue {
-
- /**
- * Driver Code
- */
- public static void main(String[] args) {
- Random rand = new Random();
-
- /* test 100 times using rand numbers */
- for (int i = 1; i <= 100; ++i) {
- /* generate number from -50 to 49 */
- int a = rand.nextInt(100) - 50;
- int b = rand.nextInt(100) - 50;
- assert min(a, b) == Math.min(a, b);
- }
+public final class MinValue {
+ private MinValue() {
}
-
/**
* Returns the smaller of two {@code int} values. That is, the result the
* argument closer to the value of {@link Integer#MIN_VALUE}. If the
diff --git a/src/test/java/com/thealgorithms/maths/MinValueTest.java b/src/test/java/com/thealgorithms/maths/MinValueTest.java
new file mode 100644
index 000000000000..beb0ccb1a571
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/MinValueTest.java
@@ -0,0 +1,14 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class MinValueTest {
+ @Test
+ public void minTest() {
+ assertEquals(-1, MinValue.min(-1, 3));
+ assertEquals(2, MinValue.min(3, 2));
+ assertEquals(5, MinValue.min(5, 5));
+ }
+}
From ced96786990696589b86cc9fa3d8bc098510dc00 Mon Sep 17 00:00:00 2001
From: Anuj Rathour
Date: Mon, 9 Oct 2023 21:03:34 +0530
Subject: [PATCH 0047/1151] Update queue readme (#4721)
---
.../datastructures/queues/README.md | 57 ++++++++++++++++---
1 file changed, 49 insertions(+), 8 deletions(-)
diff --git a/src/main/java/com/thealgorithms/datastructures/queues/README.md b/src/main/java/com/thealgorithms/datastructures/queues/README.md
index ca5e2972f8c5..ef1b89b5c9a4 100644
--- a/src/main/java/com/thealgorithms/datastructures/queues/README.md
+++ b/src/main/java/com/thealgorithms/datastructures/queues/README.md
@@ -31,17 +31,58 @@
- **Delay Queue:** Used for scheduling tasks to run after a specific delay or at a certain time. Elements are removed from the queue when their delay expires.
## Declaration
-
-`Queue queue = new PriorityQueue ();`
+`Queue queue = new PriorityQueue();`
## Important operations
-| Operations | Description |
-| ----------- | ----------- |
-|Enqueue|Adds an item to the queue|
-|Dequeue|Removes an item from the queue|
-|Front|Gets the front item from the queue|
-|Rear|Gets the last item from the queue|
+| Operations | Description |Time Complexity
+| ----------- | ----------- |-----------
+|Enqueue|Adds an item to the queue|O(1)
+|Dequeue|Removes an item from the queue|O(1)
+|Front|Gets the front item from the queue|O(1)
+|Rear|Gets the last item from the queue|O(n)
+
+## Enqueue
+ It adds an item to the rear of the queue.
+
+ For example: If we have `1, 2, 3, 4, 5` in queue, and if we call Enqueue(8),
+
+`8` will be added to last index of queue -> `1, 2, 3, 4, 5, 8`.
+## Dequeue
+
+ It removes an item to the front of the queue.
+
+ For example: If we have `1, 2, 3, 4, 5` in queue, and we call Dequeue(),
+
+`1` will be removed from front of queue and returned -> `2, 3, 4, 5`.
+
+## Front
+ It returns an item to the front of the queue.
+
+For example: If we have `1, 2, 3, 5` in queue, and we call Front(),
+
+`1` will be returned (without removing it from the queue).
+
+## Rear
+ It returns an item to the rear of the queue.
+
+ For example: If we have `1, 2, 3, 5` in queue, and we call Rear(),
+
+`5` will be returned (without removing it from the queue).
+
+# Real Life Applications
+`Task Scheduling in Operating Systems:`
+
+Processes in a multitasking system are often scheduled using queues. For example, the ready queue contains processes ready to be executed.
+
+`Multi-threaded Programming:`
+
+Queues are often used to facilitate communication and synchronization between different threads.
+
+`Breadth-First Search (BFS) in Graphs:`
+
+Queues are used in algorithms like BFS to explore a graph level by level.
+
From 17fe4298b699ff4cb6282a5e1e0edcd7541f6735 Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Tue, 10 Oct 2023 21:27:23 +0200
Subject: [PATCH 0048/1151] Add MaxValueTest and remove main from MaxValue
(#4756)
* Create MaxValueTest.java
* Update MaxValue.java
---
.../com/thealgorithms/maths/MaxValue.java | 20 ++-----------------
.../com/thealgorithms/maths/MaxValueTest.java | 14 +++++++++++++
2 files changed, 16 insertions(+), 18 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/maths/MaxValueTest.java
diff --git a/src/main/java/com/thealgorithms/maths/MaxValue.java b/src/main/java/com/thealgorithms/maths/MaxValue.java
index a4603533a2df..d88291060f51 100644
--- a/src/main/java/com/thealgorithms/maths/MaxValue.java
+++ b/src/main/java/com/thealgorithms/maths/MaxValue.java
@@ -1,24 +1,8 @@
package com.thealgorithms.maths;
-import java.util.Random;
-
-public class MaxValue {
-
- /**
- * Driver Code
- */
- public static void main(String[] args) {
- Random rand = new Random();
-
- /* test 100 times using rand numbers */
- for (int i = 1; i <= 100; ++i) {
- /* generate number from -50 to 49 */
- int a = rand.nextInt(100) - 50;
- int b = rand.nextInt(100) - 50;
- assert max(a, b) == Math.max(a, b);
- }
+public final class MaxValue {
+ private MaxValue() {
}
-
/**
* Returns the greater of two {@code int} values. That is, the result is the
* argument closer to the value of {@link Integer#MAX_VALUE}. If the
diff --git a/src/test/java/com/thealgorithms/maths/MaxValueTest.java b/src/test/java/com/thealgorithms/maths/MaxValueTest.java
new file mode 100644
index 000000000000..3c0fe8447c12
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/MaxValueTest.java
@@ -0,0 +1,14 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class MaxValueTest {
+ @Test
+ public void maxTest() {
+ assertEquals(-1, MaxValue.max(-1, -3));
+ assertEquals(3, MaxValue.max(3, 2));
+ assertEquals(5, MaxValue.max(5, 5));
+ }
+}
From 152e29034d248226395ee659ce6deb2cbbc62805 Mon Sep 17 00:00:00 2001
From: Abhinav Pandey
Date: Wed, 11 Oct 2023 17:29:55 +0530
Subject: [PATCH 0049/1151] Improved code readability and code quality (#4663)
* Fixed Small typos :-)
* Update BufferedReader.java
* Made the following changes :
* Improved readability of files and removed gramatical errors.
* Implemented data assigning instead of manually calling arr.ylength in several instances like FindMax, FindMaxRecursion etc.
* Removed unwanted params from several files
* Implemented Math methods in files math/FindMinRecursion.java and FindMaxRecursion.java
* Update src/main/java/com/thealgorithms/maths/FindMinRecursion.java
---------
Co-authored-by: Debasish Biswas
---
.../java/com/thealgorithms/maths/Average.java | 2 +-
.../thealgorithms/maths/DeterminantOfMatrix.java | 2 +-
.../java/com/thealgorithms/maths/DigitalRoot.java | 10 +++++-----
.../com/thealgorithms/maths/DistanceFormula.java | 4 ++--
.../com/thealgorithms/maths/DudeneyNumber.java | 10 +++++-----
.../java/com/thealgorithms/maths/EulerMethod.java | 2 +-
.../com/thealgorithms/maths/FindKthNumber.java | 2 +-
.../java/com/thealgorithms/maths/FindMax.java | 7 ++++---
.../com/thealgorithms/maths/FindMaxRecursion.java | 8 ++++----
.../java/com/thealgorithms/maths/FindMin.java | 2 +-
.../com/thealgorithms/maths/FindMinRecursion.java | 15 ++++++++++++---
src/main/java/com/thealgorithms/maths/GCD.java | 6 +++---
.../java/com/thealgorithms/maths/Gaussian.java | 2 +-
13 files changed, 41 insertions(+), 31 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/Average.java b/src/main/java/com/thealgorithms/maths/Average.java
index ad37b78718c3..903afbafe35f 100644
--- a/src/main/java/com/thealgorithms/maths/Average.java
+++ b/src/main/java/com/thealgorithms/maths/Average.java
@@ -23,7 +23,7 @@ public static double average(double[] numbers) {
}
/**
- * find average value of int array
+ * find average value of an int array
*
* @param numbers the array contains element and the sum does not excess long
* value limit
diff --git a/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java b/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java
index 401bedbccdc0..79b0dafad8f4 100644
--- a/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java
+++ b/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java
@@ -4,7 +4,7 @@
/*
* @author Ojasva Jain
- * Determinant of Matrix Wikipedia link : https://en.wikipedia.org/wiki/Determinant
+ * Determinant of a Matrix Wikipedia link: https://en.wikipedia.org/wiki/Determinant
*/
public class DeterminantOfMatrix {
diff --git a/src/main/java/com/thealgorithms/maths/DigitalRoot.java b/src/main/java/com/thealgorithms/maths/DigitalRoot.java
index 78066f404739..9eeb4a65f2ae 100644
--- a/src/main/java/com/thealgorithms/maths/DigitalRoot.java
+++ b/src/main/java/com/thealgorithms/maths/DigitalRoot.java
@@ -51,17 +51,17 @@ public static int digitalRoot(int n) {
}
}
- // This function is used for finding the sum of digits of number
+ // This function is used for finding the sum of the digits of number
public static int single(int n) {
if (n <= 9) { // if n becomes less than 10 than return n
return n;
} else {
return (n % 10) + single(n / 10); // n % 10 for extracting digits one by one
}
- } // n / 10 is the number obtainded after removing the digit one by one
- // Sum of digits is stored in the Stack memory and then finally returned
+ } // n / 10 is the number obtained after removing the digit one by one
+ // The Sum of digits is stored in the Stack memory and then finally returned
}
/**
- * Time Complexity : O((Number of Digits)^2) Auxiliary Space Complexity :
- * O(Number of Digits) Constraints : 1 <= n <= 10^7
+ * Time Complexity: O((Number of Digits)^2) Auxiliary Space Complexity:
+ * O(Number of Digits) Constraints: 1 <= n <= 10^7
*/
diff --git a/src/main/java/com/thealgorithms/maths/DistanceFormula.java b/src/main/java/com/thealgorithms/maths/DistanceFormula.java
index 9a2654dbeedb..6efc2fbdff5d 100644
--- a/src/main/java/com/thealgorithms/maths/DistanceFormula.java
+++ b/src/main/java/com/thealgorithms/maths/DistanceFormula.java
@@ -16,7 +16,7 @@ public static int hammingDistance(int[] b1, int[] b2) {
int d = 0;
if (b1.length != b2.length) {
- return -1; // error, both array must be have the same length
+ return -1; // error, both arrays must have the same length
}
for (int i = 0; i < b1.length; i++) {
@@ -31,7 +31,7 @@ public static double minkowskiDistance(double[] p1, double[] p2, int p) {
double distance = 0.0;
if (p1.length != p2.length) {
- return -1; // error, both array must be have the same length
+ return -1; // error, both arrays must have the same length
}
for (int i = 0; i < p1.length; i++) {
diff --git a/src/main/java/com/thealgorithms/maths/DudeneyNumber.java b/src/main/java/com/thealgorithms/maths/DudeneyNumber.java
index 69231af7bb85..3bb56c5ccdb7 100644
--- a/src/main/java/com/thealgorithms/maths/DudeneyNumber.java
+++ b/src/main/java/com/thealgorithms/maths/DudeneyNumber.java
@@ -16,21 +16,21 @@ public static boolean isDudeney(int n) {
if (cube_root * cube_root * cube_root != n) {
return false;
}
- int sum_of_digits = 0; // Stores the sums of the digit of the entered number
+ int sum_of_digits = 0; // Stores the sums of the digits of the entered number
int temp = n; // A temporary variable to store the entered number
- // Loop to calculate sum of the digits.
+ // Loop to calculate the sum of the digits.
while (temp > 0) {
- // Extracting Last digit of the number
+ // Extracting the Last digit of the number
int rem = temp % 10;
- // Calculating sum of digits.
+ // Calculating the sum of digits.
sum_of_digits += rem;
// Removing the last digit
temp /= 10;
}
- // If the cube root of the number is not equal to the sum of its digits we return false.
+ // If the cube root of the number is not equal to the sum of its digits, we return false.
return cube_root == sum_of_digits;
}
}
diff --git a/src/main/java/com/thealgorithms/maths/EulerMethod.java b/src/main/java/com/thealgorithms/maths/EulerMethod.java
index 336e23dd489c..40e654626a23 100644
--- a/src/main/java/com/thealgorithms/maths/EulerMethod.java
+++ b/src/main/java/com/thealgorithms/maths/EulerMethod.java
@@ -87,7 +87,7 @@ public static ArrayList eulerFull(double xStart, double xEnd, double s
double xCurrent = xStart;
while (xCurrent < xEnd) {
- // Euler method for next step
+ // Euler's method for next step
yCurrent = eulerStep(xCurrent, stepSize, yCurrent, differentialEquation);
xCurrent += stepSize;
double[] point = {xCurrent, yCurrent};
diff --git a/src/main/java/com/thealgorithms/maths/FindKthNumber.java b/src/main/java/com/thealgorithms/maths/FindKthNumber.java
index d869ca47c759..bcb83b5ee2fc 100644
--- a/src/main/java/com/thealgorithms/maths/FindKthNumber.java
+++ b/src/main/java/com/thealgorithms/maths/FindKthNumber.java
@@ -11,7 +11,7 @@ public class FindKthNumber {
private static final Random random = new Random();
public static void main(String[] args) {
- /* generate array with random size and random elements */
+ /* generate an array with random size and random elements */
int[] nums = generateArray(100);
/* get 3th largest element */
diff --git a/src/main/java/com/thealgorithms/maths/FindMax.java b/src/main/java/com/thealgorithms/maths/FindMax.java
index 76bde5ff600f..0ff2bdd191ac 100644
--- a/src/main/java/com/thealgorithms/maths/FindMax.java
+++ b/src/main/java/com/thealgorithms/maths/FindMax.java
@@ -12,11 +12,12 @@ private FindMax() {
* @return the maximum value stored in the input array
*/
public static int findMax(final int[] array) {
- if (array.length == 0) {
- throw new IllegalArgumentException("array must be non-empty.");
+ int n = array.length;
+ if (n == 0) {
+ throw new IllegalArgumentException("Array must be non-empty.");
}
int max = array[0];
- for (int i = 1; i < array.length; i++) {
+ for (int i = 1; i < n; i++) {
if (array[i] > max) {
max = array[i];
}
diff --git a/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java b/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
index 574fe5f2b1b8..950a0ebe0085 100644
--- a/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
+++ b/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java
@@ -5,7 +5,7 @@ public final class FindMaxRecursion {
private FindMaxRecursion() {
}
/**
- * Get max of array using divide and conquer algorithm
+ * Get max of an array using divide and conquer algorithm
*
* @param array contains elements
* @param low the index of the first element
@@ -14,7 +14,7 @@ private FindMaxRecursion() {
*/
public static int max(final int[] array, final int low, final int high) {
if (array.length == 0) {
- throw new IllegalArgumentException("array must be non-empty.");
+ throw new IllegalArgumentException("Array must be non-empty.");
}
if (low == high) {
return array[low]; // or array[high]
@@ -25,11 +25,11 @@ public static int max(final int[] array, final int low, final int high) {
int leftMax = max(array, low, mid); // get max in [low, mid]
int rightMax = max(array, mid + 1, high); // get max in [mid+1, high]
- return leftMax < rightMax ? rightMax : leftMax;
+ return Math.max(leftMax, rightMax);
}
/**
- * Get max of array using recursion algorithm
+ * Get max of an array using recursion algorithm
*
* @param array contains elements
* @return max value of {@code array}
diff --git a/src/main/java/com/thealgorithms/maths/FindMin.java b/src/main/java/com/thealgorithms/maths/FindMin.java
index 10a03c801098..76fa2e815ee0 100644
--- a/src/main/java/com/thealgorithms/maths/FindMin.java
+++ b/src/main/java/com/thealgorithms/maths/FindMin.java
@@ -13,7 +13,7 @@ private FindMin() {
*/
public static int findMin(final int[] array) {
if (array.length == 0) {
- throw new IllegalArgumentException("array must be non-empty.");
+ throw new IllegalArgumentException("Array must be non-empty.");
}
int min = array[0];
for (int i = 1; i < array.length; i++) {
diff --git a/src/main/java/com/thealgorithms/maths/FindMinRecursion.java b/src/main/java/com/thealgorithms/maths/FindMinRecursion.java
index 6ffe034ee40f..a2cf1b36d6cb 100644
--- a/src/main/java/com/thealgorithms/maths/FindMinRecursion.java
+++ b/src/main/java/com/thealgorithms/maths/FindMinRecursion.java
@@ -4,6 +4,16 @@ public final class FindMinRecursion {
private FindMinRecursion() {
}
+
+ /**
+ * Get min of an array using divide and conquer algorithm
+ *
+ * @param array contains elements
+ * @param low the index of the first element
+ * @param high the index of the last element
+ * @return min of {@code array}
+ */
+
public static int min(final int[] array, final int low, final int high) {
if (array.length == 0) {
throw new IllegalArgumentException("array must be non-empty.");
@@ -17,14 +27,13 @@ public static int min(final int[] array, final int low, final int high) {
int leftMin = min(array, low, mid); // get min in [low, mid]
int rightMin = min(array, mid + 1, high); // get min in [mid+1, high]
- return leftMin > rightMin ? rightMin : leftMin;
+ return Math.min(leftMin, rightMin);
}
/**
- * Get min of array using recursion algorithm
+ * Get min of an array using recursion algorithm
*
* @param array contains elements
- * @param len length of given array
* @return min value of {@code array}
*/
public static int min(final int[] array) {
diff --git a/src/main/java/com/thealgorithms/maths/GCD.java b/src/main/java/com/thealgorithms/maths/GCD.java
index 3a69fcab413f..0f3125bde209 100644
--- a/src/main/java/com/thealgorithms/maths/GCD.java
+++ b/src/main/java/com/thealgorithms/maths/GCD.java
@@ -1,15 +1,15 @@
package com.thealgorithms.maths;
/**
- * This is Euclid's algorithm which is used to find the greatest common
- * denominator Overide function name gcd
+ * This is Euclid's algorithm, used to find the greatest common
+ * denominator Override function name gcd
*
* @author Oskar Enmalm 3/10/17
*/
public class GCD {
/**
- * get greatest common divisor
+ * get the greatest common divisor
*
* @param num1 the first number
* @param num2 the second number
diff --git a/src/main/java/com/thealgorithms/maths/Gaussian.java b/src/main/java/com/thealgorithms/maths/Gaussian.java
index fd0f86d89f89..442c51e9d32d 100644
--- a/src/main/java/com/thealgorithms/maths/Gaussian.java
+++ b/src/main/java/com/thealgorithms/maths/Gaussian.java
@@ -38,7 +38,7 @@ public static double[][] gaussianElimination(int mat_size, int i, double[][] mat
return mat;
}
- // calculate the x_1, x_2,... values of the gaussian and save it in an arraylist.
+ // calculate the x_1, x_2, ... values of the gaussian and save it in an arraylist.
public static ArrayList valueOfGaussian(int mat_size, double[][] x, double[][] mat) {
ArrayList answerArray = new ArrayList();
int i, j;
From e9bbf35ff9ab85dd968fcec14f0a4b057ecccb8b Mon Sep 17 00:00:00 2001
From: Ricardo Ramos <36955909+ricardo-ramos-moura@users.noreply.github.com>
Date: Wed, 11 Oct 2023 18:21:53 -0300
Subject: [PATCH 0050/1151] Add `FloorTest` and clean-up `Floor` (#4769)
Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
Co-authored-by: Ricardo Ramos <0102016812@grupotel.corp>
---
DIRECTORY.md | 103 ++++++++++++++----
.../java/com/thealgorithms/maths/Floor.java | 11 +-
.../com/thealgorithms/maths/FloorTest.java | 28 +++++
3 files changed, 114 insertions(+), 28 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/maths/FloorTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 3aa2bde37be0..6de516618484 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -19,10 +19,14 @@
* [PowerSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/PowerSum.java)
* [WordSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/WordSearch.java)
* bitmanipulation
+ * [HighestSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java)
+ * [IndexOfRightMostSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java)
* [IsEven](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java)
* [IsPowerTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java)
+ * [NonRepeatingNumberFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java)
* [NumbersDifferentSigns](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java)
* [ReverseBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java)
+ * [SingleBitOperations](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java)
* ciphers
* a5
* [A5Cipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java)
@@ -77,9 +81,9 @@
* [LFUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java)
* [LRUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java)
* [MRUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java)
- * disjointsets
- * [DisjointSets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsets/DisjointSets.java)
- * [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsets/Node.java)
+ * disjointsetunion
+ * [DisjointSetUnion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java)
+ * [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java)
* dynamicarray
* [DynamicArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java)
* graphs
@@ -129,7 +133,10 @@
* [Merge K SortedLinkedlist](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/Merge_K_SortedLinkedlist.java)
* [MergeSortedArrayList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java)
* [MergeSortedSinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java)
+ * [QuickSortLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java)
* [RandomNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/RandomNode.java)
+ * [ReverseKGroup](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java)
+ * [RotateSinglyLinkedLists](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java)
* [SearchSinglyLinkedListRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java)
* [SinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java)
* [SkipList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java)
@@ -142,17 +149,7 @@
* [PriorityQueues](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java)
* [Queues](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/Queues.java)
* stacks
- * [BalancedBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/BalancedBrackets.java)
- * [CalculateMaxOfMin](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/CalculateMaxOfMin.java)
- * [DecimalToAnyUsingStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/DecimalToAnyUsingStack.java)
- * [DuplicateBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/DuplicateBrackets.java)
- * [InfixToPostfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/InfixToPostfix.java)
- * [LargestRectangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/LargestRectangle.java)
- * [MaximumMinimumWindow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/MaximumMinimumWindow.java)
- * [NextGraterElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/NextGraterElement.java)
- * [NextSmallerElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/NextSmallerElement.java)
* [NodeStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java)
- * [PostfixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/PostfixToInfix.java)
* [ReverseStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java)
* [StackArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java)
* [StackArrayList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/StackArrayList.java)
@@ -214,7 +211,6 @@
* [CoinChange](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java)
* [CountFriendsPairing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java)
* [DiceThrow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java)
- * [DyanamicProgrammingKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/DyanamicProgrammingKnapsack.java)
* [EditDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java)
* [EggDropping](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java)
* [Fibonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java)
@@ -244,9 +240,15 @@
* [SubsetSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java)
* [Sum Of Subset](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Sum_Of_Subset.java)
* [UniquePaths](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java)
+ * [WildcardMatching](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java)
* [WineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java)
* geometry
* [GrahamScan](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/geometry/GrahamScan.java)
+ * greedyalgorithms
+ * [ActivitySelection](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java)
+ * [CoinChange](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java)
+ * [FractionalKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java)
+ * [JobSequencing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java)
* io
* [BufferedReader](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/io/BufferedReader.java)
* maths
@@ -307,7 +309,9 @@
* [MagicSquare](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MagicSquare.java)
* [MatrixUtil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MatrixUtil.java)
* [MaxValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MaxValue.java)
+ * [Means](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Means.java)
* [Median](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Median.java)
+ * [MillerRabinPrimalityCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java)
* [MinValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MinValue.java)
* [MobiusFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MobiusFunction.java)
* [Mode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Mode.java)
@@ -325,13 +329,14 @@
* [PollardRho](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PollardRho.java)
* [Pow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Pow.java)
* [PowerOfTwoOrNot](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java)
- * [PowRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PowRecursion.java)
+ * [PowerUsingRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java)
* [PrimeCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PrimeCheck.java)
* [PrimeFactorization](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PrimeFactorization.java)
* [PronicNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PronicNumber.java)
* [PythagoreanTriple](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java)
* [ReverseNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/ReverseNumber.java)
* [RomanNumeralUtil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java)
+ * [SecondMinMax](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SecondMinMax.java)
* [SimpsonIntegration](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java)
* [SquareFreeInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java)
* [SquareRootWithBabylonianMethod](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java)
@@ -355,13 +360,21 @@
* [ColorContrastRatio](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java)
* [InverseOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java)
* [matrixTranspose](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/matrixTranspose.java)
+ * [MedianOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java)
* [MedianOfRunningArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java)
+ * [MedianOfRunningArrayByte](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java)
+ * [MedianOfRunningArrayDouble](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java)
+ * [MedianOfRunningArrayFloat](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java)
+ * [MedianOfRunningArrayInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java)
+ * [MedianOfRunningArrayLong](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java)
+ * [MirrorOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java)
* [PalindromePrime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/PalindromePrime.java)
* [PalindromeSinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java)
* [RangeInSortedArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java)
* [Sort012D](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/Sort012D.java)
* [Sparcity](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/Sparcity.java)
* [ThreeSumProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java)
+ * [TwoSumProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/TwoSumProblem.java)
* [WordBoggle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/WordBoggle.java)
* others
* [ArrayLeftRotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ArrayLeftRotation.java)
@@ -412,7 +425,6 @@
* [RotateMatriceBy90Degree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RotateMatriceBy90Degree.java)
* [SieveOfEratosthenes](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java)
* [SkylineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/SkylineProblem.java)
- * [StackPostfixNotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/StackPostfixNotation.java)
* [StringMatchFiniteAutomata](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java)
* [Sudoku](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Sudoku.java)
* [TopKWords](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TopKWords.java)
@@ -421,6 +433,7 @@
* [Verhoeff](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Verhoeff.java)
* scheduling
* [FCFSScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java)
+ * [PreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java)
* [RRScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RRScheduling.java)
* [SJFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java)
* searches
@@ -444,6 +457,7 @@
* [PerfectBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java)
* [QuickSelect](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/QuickSelect.java)
* [RabinKarpAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java)
+ * [RecursiveBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java)
* [RowColumnWiseSorted2dArrayBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java)
* [SaddlebackSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java)
* [SearchInARowAndColWiseSortedMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java)
@@ -495,7 +509,20 @@
* [TopologicalSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TopologicalSort.java)
* [TreeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TreeSort.java)
* [WiggleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/WiggleSort.java)
+ * stacks
+ * [BalancedBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java)
+ * [CalculateMaxOfMin](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/CalculateMaxOfMin.java)
+ * [DecimalToAnyUsingStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java)
+ * [DuplicateBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java)
+ * [InfixToPostfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java)
+ * [LargestRectangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/LargestRectangle.java)
+ * [MaximumMinimumWindow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java)
+ * [NextGraterElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextGraterElement.java)
+ * [NextSmallerElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java)
+ * [PostfixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java)
+ * [StackPostfixNotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java)
* strings
+ * [AhoCorasick](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/AhoCorasick.java)
* [Alphabetical](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Alphabetical.java)
* [Anagrams](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Anagrams.java)
* [CharactersSame](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/CharactersSame.java)
@@ -514,6 +541,7 @@
* [PermuteString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/PermuteString.java)
* [ReverseString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ReverseString.java)
* [ReverseStringRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ReverseStringRecursive.java)
+ * [ReverseWordsInString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ReverseWordsInString.java)
* [Rotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Rotation.java)
* [StringCompression](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/StringCompression.java)
* [Upper](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Upper.java)
@@ -536,10 +564,14 @@
* [PowerSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PowerSumTest.java)
* [WordSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/WordSearchTest.java)
* bitmanipulation
+ * [HighestSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java)
+ * [IndexOfRightMostSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java)
* [IsEvenTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java)
* [IsPowerTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java)
+ * [NonRepeatingNumberFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java)
* [NumbersDifferentSignsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java)
* [ReverseBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java)
+ * [SingleBitOperationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java)
* ciphers
* a5
* [LFSRTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java)
@@ -573,6 +605,8 @@
* [LFUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java)
* [LRUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java)
* [MRUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java)
+ * disjointsetunion
+ * [DisjointSetUnionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java)
* graphs
* [HamiltonianCycleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java)
* [KosarajuTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java)
@@ -589,6 +623,9 @@
* [FibonacciHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java)
* [LeftistHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java)
* lists
+ * [QuickSortLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java)
+ * [ReverseKGroupTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java)
+ * [RotateSinglyLinkedListsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java)
* [SinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java)
* [SkipListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java)
* queues
@@ -622,13 +659,22 @@
* [climbStairsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/climbStairsTest.java)
* [EggDroppingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/EggDroppingTest.java)
* [KnapsackMemoizationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java)
+ * [KnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java)
* [LevenshteinDistanceTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java)
* [MinimumPathSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java)
+ * [MinimumSumPartitionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java)
* [OptimalJobSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java)
* [PartitionProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java)
* [SubsetCountTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java)
+ * [UniquePathsTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java)
+ * [WildcardMatchingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java)
* geometry
* [GrahamScanTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/GrahamScanTest.java)
+ * greedyalgorithms
+ * [ActivitySelectionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java)
+ * [CoinChangeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java)
+ * [FractionalKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java)
+ * [JobSequencingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java)
* io
* [BufferedReaderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/io/BufferedReaderTest.java)
* maths
@@ -655,8 +701,11 @@
* [FFTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FFTTest.java)
* [FibonacciJavaStreamsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java)
* [FibonacciNumberCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciNumberCheckTest.java)
+ * [FindMaxRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java)
* [FindMaxTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMaxTest.java)
+ * [FindMinRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java)
* [FindMinTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMinTest.java)
+ * [FloorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FloorTest.java)
* [FrizzyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FrizzyNumberTest.java)
* [GaussianTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GaussianTest.java)
* [GCDTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GCDTest.java)
@@ -670,7 +719,11 @@
* [LiouvilleLambdaFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java)
* [LongDivisionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LongDivisionTest.java)
* [LucasSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LucasSeriesTest.java)
+ * [MaxValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MaxValueTest.java)
+ * [MeansTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MeansTest.java)
* [MedianTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MedianTest.java)
+ * [MillerRabinPrimalityCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java)
+ * [MinValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MinValueTest.java)
* [MobiusFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java)
* [NthUglyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/NthUglyNumberTest.java)
* [PalindromeNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PalindromeNumberTest.java)
@@ -682,11 +735,13 @@
* [PerimeterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PerimeterTest.java)
* [PollardRhoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PollardRhoTest.java)
* [PowerOfTwoOrNotTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java)
+ * [PowerUsingRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java)
* [PrimeCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PrimeCheckTest.java)
* [PrimeFactorizationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java)
* [PronicNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PronicNumberTest.java)
* [PythagoreanTripleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java)
* [ReverseNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ReverseNumberTest.java)
+ * [SecondMinMaxTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java)
* [SquareFreeIntegerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java)
* [SquareRootwithBabylonianMethodTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java)
* [SquareRootWithNewtonRaphsonTestMethod](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonTestMethod.java)
@@ -699,10 +754,15 @@
* [TestArmstrong](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/TestArmstrong.java)
* [TwinPrimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/TwinPrimeTest.java)
* [VolumeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/VolumeTest.java)
+ * misc
+ * [MedianOfMatrixtest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java)
+ * [MedianOfRunningArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java)
+ * [MirrorOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java)
+ * [PalindromeSinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/PalindromeSinglyLinkedListTest.java)
+ * [TwoSumProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/TwoSumProblemTest.java)
* others
* [ArrayLeftRotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java)
* [BestFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/BestFitCPUTest.java)
- * [CalculateMaxOfMinTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/CalculateMaxOfMinTest.java)
* cn
* [HammingDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/cn/HammingDistanceTest.java)
* [ConwayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ConwayTest.java)
@@ -723,13 +783,12 @@
* [NextFitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/NextFitTest.java)
* [PasswordGenTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/PasswordGenTest.java)
* [SieveOfEratosthenesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/SieveOfEratosthenesTest.java)
- * [StackPostfixNotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/StackPostfixNotationTest.java)
* [TestPrintMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java)
* [TwoPointersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TwoPointersTest.java)
- * [UniquePathsTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/UniquePathsTests.java)
* [WorstFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java)
* scheduling
* [FCFSSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java)
+ * [PreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java)
* [RRSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java)
* [SJFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java)
* searches
@@ -741,6 +800,7 @@
* [OrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java)
* [QuickSelectTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/QuickSelectTest.java)
* [RabinKarpAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java)
+ * [RecursiveBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java)
* [RowColumnWiseSorted2dArrayBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java)
* [sortOrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearchTest.java)
* [TestSearchInARowAndColWiseSortedMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java)
@@ -775,7 +835,11 @@
* [TopologicalSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java)
* [TreeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TreeSortTest.java)
* [WiggleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java)
+ * stacks
+ * [CalculateMaxOfMinTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/CalculateMaxOfMinTest.java)
+ * [StackPostfixNotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java)
* strings
+ * [AhoCorasickTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java)
* [AlphabeticalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java)
* [AnagramsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AnagramsTest.java)
* [CharacterSameTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CharacterSameTest.java)
@@ -792,6 +856,7 @@
* [PangramTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/PangramTest.java)
* [ReverseStringRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ReverseStringRecursiveTest.java)
* [ReverseStringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ReverseStringTest.java)
+ * [ReverseWordsInStringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java)
* [RotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/RotationTest.java)
* [StringCompressionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/StringCompressionTest.java)
* [UpperTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/UpperTest.java)
diff --git a/src/main/java/com/thealgorithms/maths/Floor.java b/src/main/java/com/thealgorithms/maths/Floor.java
index bd4df6fcb852..271fc42d0d17 100644
--- a/src/main/java/com/thealgorithms/maths/Floor.java
+++ b/src/main/java/com/thealgorithms/maths/Floor.java
@@ -1,15 +1,8 @@
package com.thealgorithms.maths;
-import java.util.Random;
+public final class Floor {
-public class Floor {
-
- public static void main(String[] args) {
- Random random = new Random();
- for (int i = 1; i <= 1000; ++i) {
- double randomNumber = random.nextDouble();
- assert floor(randomNumber) == Math.floor(randomNumber);
- }
+ private Floor() {
}
/**
diff --git a/src/test/java/com/thealgorithms/maths/FloorTest.java b/src/test/java/com/thealgorithms/maths/FloorTest.java
new file mode 100644
index 000000000000..19aed70ccb71
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/FloorTest.java
@@ -0,0 +1,28 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+public class FloorTest {
+ @Test
+ public void testFloorWholeNumber() {
+ assertEquals(0, Floor.floor(0));
+ assertEquals(1, Floor.floor(1));
+ assertEquals(-1, Floor.floor(-1));
+ assertEquals(42, Floor.floor(42));
+ assertEquals(-42, Floor.floor(-42));
+ }
+
+ @Test
+ public void testFloorDoubleNumber() {
+ assertEquals(0, Floor.floor(0.1));
+ assertEquals(1, Floor.floor(1.9));
+ assertEquals(-2, Floor.floor(-1.1));
+ assertEquals(-43, Floor.floor(-42.7));
+ }
+
+ @Test
+ public void testFloorNegativeZero() {
+ assertEquals(-0.0, Floor.floor(-0.0));
+ }
+}
From 1dc64b16859d95446a8bfe1c50692ce57316bc42 Mon Sep 17 00:00:00 2001
From: "D.Sunil"
Date: Fri, 13 Oct 2023 01:43:32 +0530
Subject: [PATCH 0051/1151] Update BinarySearch (#4747)
---
.../searches/PerfectBinarySearch.java | 62 +++++++++++++------
.../searches/PerfectBinarySearchTest.java | 43 +++++++++++++
2 files changed, 87 insertions(+), 18 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java
diff --git a/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java b/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java
index bfeb5efc3a62..495e2e41bc5b 100644
--- a/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java
+++ b/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java
@@ -1,28 +1,54 @@
package com.thealgorithms.searches;
-class PerfectBinarySearch {
+import com.thealgorithms.devutils.searches.SearchAlgorithm;
- static int binarySearch(int[] arr, int target) {
- int low = 0;
- int high = arr.length - 1;
+/**
+ * Binary search is one of the most popular algorithms The algorithm finds the
+ * position of a target value within a sorted array
+ *
+ *
+ * Worst-case performance O(log n) Best-case performance O(1) Average
+ * performance O(log n) Worst-case space complexity O(1)
+ *
+ * @author D Sunil (https://github.com/sunilnitdgp)
+ * @see SearchAlgorithm
+ */
- while (low <= high) {
- int mid = (low + high) / 2;
+public class PerfectBinarySearch implements SearchAlgorithm {
- if (arr[mid] == target) {
- return mid;
- } else if (arr[mid] > target) {
- high = mid - 1;
+ /**
+ * @param array is an array where the element should be found
+ * @param key is an element which should be found
+ * @param is any comparable type
+ * @return index of the element
+ */
+ @Override
+ public > int find(T[] array, T key) {
+ return search(array, key, 0, array.length - 1);
+ }
+
+ /**
+ * This method implements the Generic Binary Search iteratively.
+ *
+ * @param array The array to make the binary search
+ * @param key The number you are looking for
+ * @return the location of the key, or -1 if not found
+ */
+ private static > int search(T[] array, T key, int left, int right) {
+ while (left <= right) {
+ int median = (left + right) >>> 1;
+ int comp = key.compareTo(array[median]);
+
+ if (comp == 0) {
+ return median; // Key found
+ }
+
+ if (comp < 0) {
+ right = median - 1; // Adjust the right bound
} else {
- low = mid + 1;
+ left = median + 1; // Adjust the left bound
}
}
- return -1;
- }
-
- public static void main(String[] args) {
- int[] array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- assert PerfectBinarySearch.binarySearch(array, -1) == -1;
- assert PerfectBinarySearch.binarySearch(array, 11) == -1;
+ return -1; // Key not found
}
}
diff --git a/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java b/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java
new file mode 100644
index 000000000000..0ba0b03b33b4
--- /dev/null
+++ b/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java
@@ -0,0 +1,43 @@
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.thealgorithms.searches.PerfectBinarySearch;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author D Sunil (https://github.com/sunilnitdgp)
+ * @see PerfectBinarySearch
+ */
+public class PerfectBinarySearchTest {
+
+ @Test
+ public void testIntegerBinarySearch() {
+ Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ PerfectBinarySearch binarySearch = new PerfectBinarySearch<>();
+
+ // Test cases for elements present in the array
+ assertEquals(0, binarySearch.find(array, 1)); // First element
+ assertEquals(4, binarySearch.find(array, 5)); // Middle element
+ assertEquals(9, binarySearch.find(array, 10)); // Last element
+ assertEquals(6, binarySearch.find(array, 7)); // Element in the middle
+
+ // Test cases for elements not in the array
+ assertEquals(-1, binarySearch.find(array, 0)); // Element before the array
+ assertEquals(-1, binarySearch.find(array, 11)); // Element after the array
+ assertEquals(-1, binarySearch.find(array, 100)); // Element not in the array
+ }
+
+ @Test
+ public void testStringBinarySearch() {
+ String[] array = {"apple", "banana", "cherry", "date", "fig"};
+ PerfectBinarySearch binarySearch = new PerfectBinarySearch<>();
+
+ // Test cases for elements not in the array
+ assertEquals(-1, binarySearch.find(array, "apricot")); // Element not in the array
+ assertEquals(-1, binarySearch.find(array, "bananaa")); // Element not in the array
+
+ // Test cases for elements present in the array
+ assertEquals(0, binarySearch.find(array, "apple")); // First element
+ assertEquals(2, binarySearch.find(array, "cherry")); // Middle element
+ assertEquals(4, binarySearch.find(array, "fig")); // Last element
+ }
+}
From 24a82230626e986392bcba7dc86b80118aefcdc3 Mon Sep 17 00:00:00 2001
From: Pronay Debnath
Date: Sat, 14 Oct 2023 00:53:30 +0530
Subject: [PATCH 0052/1151] Added [FEATURE REQUEST] Golden Ration formula to
find Nth Fibonacci number #4505 (#4513)
* Create FibonacciNumber.java
* Update FibonacciNumber.java
* Update FibonacciNumber.java
* Update src/main/java/com/thealgorithms/maths/FibonacciNumber.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/FibonacciNumber.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update FibonacciNumber.java
* Update FibonacciNumber.java
* Update FibonacciNumber.java
* Update FibonacciNumber.java
* Create FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumber.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update src/main/java/com/thealgorithms/maths/FibonacciNumber.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update FibonacciNumber.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumber.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Delete src/main/java/com/thealgorithms/maths/FibonacciNumberTest.java
* Create FibonacciNumberTest.java
* Update FibonacciNumber.java
* Update FibonacciNumberTest.java
* Update FibonacciNumber.java
* Update FibonacciNumber.java
* Update FibonacciNumber.java
* Update FibonacciNumber.java
* Update FibonacciNumberTest.java
* Update src/test/java/com/thealgorithms/maths/FibonacciNumberTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/FibonacciNumber.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Create FibonacciCalculator.java
* Update FibonacciNumberTest.java
* Update and rename FibonacciCalculator.java to FibCalc.java
* Update FibonacciNumberTest.java
* Update FibCalc.java
* Update FibonacciNumber.java
* Delete src/test/java/com/thealgorithms/maths/FibCalc.java
* Create FibCalc.java
* Update FibonacciNumberTest.java
* Update FibCalc.java
* Update FibonacciNumberTest.java
* Update FibonacciNumber.java
* Update FibonacciNumberTest.java
* Update FibonacciNumber.java
* Update FibonacciNumber.java
* Update FibonacciNumber.java
* Update FibonacciNumber.java
* Update FibonacciNumberTest.java
* Update FibonacciNumber.java
* fix: use proper name
* fix: use proper class name
* tests: add `returnsCorrectValues`
* Update and rename FibCalc.java to Fibonacci.java
* Update Fibonacci.java
* Update FibonacciNumber.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update Fibonacci.java
* Update FibonacciNumber.java
* Update and rename FibCalcTest.java to FibonacciTest.java
* Update FibonacciNumber.java
* Update Fibonacci.java
* Update Fibonacci.java
* Update Fibonacci.java
* Update FibonacciTest.java
* Update Fibonacci.java
* Update src/main/java/com/thealgorithms/maths/Fibonacci.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/FibonacciNumber.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/maths/FibonacciNumberTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/maths/FibonacciNumberTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update FibonacciTest.java
* Update FibonacciNumberTest.java
* Update FibonacciNumberTest.java
* Update FibonacciTest.java
* Update src/main/java/com/thealgorithms/maths/Fibonacci.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/FibonacciNumber.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/maths/FibonacciNumberTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/maths/FibonacciTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/Fibonacci.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/FibonacciNumber.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/FibonacciNumber.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/FibonacciNumber.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/FibonacciNumber.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/maths/FibonacciNumber.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/maths/FibonacciNumberTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/maths/FibonacciNumberTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/maths/FibonacciNumberTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update FibonacciNumber.java
* Update FibonacciNumber.java
* Update Fibonacci.java
* Update FibonacciNumber.java
* Update and rename FibonacciNumber.java to FibonacciNumberGoldenRation.java
* Update and rename FibonacciNumberTest.java to FibonacciNumberGoldenRationTest.java
* Update Fibonacci.java
* Update FibonacciNumberGoldenRation.java
* Update FibonacciNumberGoldenRationTest.java
* Update FibonacciTest.java
* Update Fibonacci.java
* Update FibonacciNumberGoldenRationTest.java
* Update FibonacciNumberGoldenRationTest.java
* Update FibonacciNumberGoldenRation.java
* Update FibonacciNumberGoldenRation.java
* Update FibonacciNumberGoldenRationTest.java
* Update FibonacciNumberGoldenRationTest.java
* Update src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update and rename Fibonacci.java to FibonacciLoop.java
* Update FibonacciNumberGoldenRation.java
* Update FibonacciNumberGoldenRationTest.java
* Update and rename FibonacciTest.java to FibonacciLoopTest.java
* Update FibonacciLoop.java
* Update FibonacciLoop.java
* Update FibonacciNumberGoldenRation.java
* docs: add missing dot
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Co-authored-by: vil02
---
.../thealgorithms/maths/FibonacciLoop.java | 41 +++++++++++++++
.../maths/FibonacciNumberGoldenRation.java | 50 +++++++++++++++++++
.../maths/FibonacciLoopTest.java | 36 +++++++++++++
.../FibonacciNumberGoldenRationTest.java | 29 +++++++++++
4 files changed, 156 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/maths/FibonacciLoop.java
create mode 100644 src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java
create mode 100644 src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java
create mode 100644 src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java
diff --git a/src/main/java/com/thealgorithms/maths/FibonacciLoop.java b/src/main/java/com/thealgorithms/maths/FibonacciLoop.java
new file mode 100644
index 000000000000..de23a4305c3f
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/FibonacciLoop.java
@@ -0,0 +1,41 @@
+package com.thealgorithms.maths;
+
+import java.math.BigInteger;
+
+/**
+ * This class provides methods for calculating Fibonacci numbers using BigInteger for large values of 'n'.
+ */
+public final class FibonacciLoop {
+
+ private FibonacciLoop() {
+ // Private constructor to prevent instantiation of this utility class.
+ }
+
+ /**
+ * Calculates the nth Fibonacci number.
+ *
+ * @param n The index of the Fibonacci number to calculate.
+ * @return The nth Fibonacci number as a BigInteger.
+ * @throws IllegalArgumentException if the input 'n' is a negative integer.
+ */
+ public static BigInteger compute(final int n) {
+ if (n < 0) {
+ throw new IllegalArgumentException("Input 'n' must be a non-negative integer.");
+ }
+
+ if (n <= 1) {
+ return BigInteger.valueOf(n);
+ }
+
+ BigInteger prev = BigInteger.ZERO;
+ BigInteger current = BigInteger.ONE;
+
+ for (int i = 2; i <= n; i++) {
+ BigInteger next = prev.add(current);
+ prev = current;
+ current = next;
+ }
+
+ return current;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java b/src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java
new file mode 100644
index 000000000000..4df37a40f541
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java
@@ -0,0 +1,50 @@
+package com.thealgorithms.maths;
+
+/**
+ * This class provides methods for calculating Fibonacci numbers using Binet's formula.
+ * Binet's formula is based on the golden ratio and allows computing Fibonacci numbers efficiently.
+ *
+ * @see Binet's formula on Wikipedia
+ */
+public final class FibonacciNumberGoldenRation {
+ private FibonacciNumberGoldenRation() {
+ // Private constructor to prevent instantiation of this utility class.
+ }
+
+ /**
+ * Compute the limit for 'n' that fits in a long data type.
+ * Reducing the limit to 70 due to potential floating-point arithmetic errors
+ * that may result in incorrect results for larger inputs.
+ */
+ public static final int MAX_ARG = 70;
+
+ /**
+ * Calculates the nth Fibonacci number using Binet's formula.
+ *
+ * @param n The index of the Fibonacci number to calculate.
+ * @return The nth Fibonacci number as a long.
+ * @throws IllegalArgumentException if the input 'n' is negative or exceeds the range of a long data type.
+ */
+ public static long compute(int n) {
+ if (n < 0) {
+ throw new IllegalArgumentException("Input 'n' must be a non-negative integer.");
+ }
+
+ if (n > MAX_ARG) {
+ throw new IllegalArgumentException("Input 'n' is too big to give accurate result.");
+ }
+
+ if (n <= 1) {
+ return n;
+ }
+
+ // Calculate the nth Fibonacci number using the golden ratio formula
+ final double sqrt5 = Math.sqrt(5);
+ final double phi = (1 + sqrt5) / 2;
+ final double psi = (1 - sqrt5) / 2;
+ final double result = (Math.pow(phi, n) - Math.pow(psi, n)) / sqrt5;
+
+ // Round to the nearest integer and return as a long
+ return Math.round(result);
+ }
+}
diff --git a/src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java b/src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java
new file mode 100644
index 000000000000..93aec39765d4
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java
@@ -0,0 +1,36 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.math.BigInteger;
+import org.junit.jupiter.api.Test;
+
+public class FibonacciLoopTest {
+ @Test
+ public void checkValueAtZero() {
+ assertEquals(BigInteger.ZERO, FibonacciLoop.compute(0));
+ }
+
+ @Test
+ public void checkValueAtOne() {
+ assertEquals(BigInteger.ONE, FibonacciLoop.compute(1));
+ }
+
+ @Test
+ public void checkValueAtTwo() {
+ assertEquals(BigInteger.ONE, FibonacciLoop.compute(2));
+ }
+
+ @Test
+ public void checkRecurrenceRelation() {
+ for (int i = 0; i < 100; ++i) {
+ assertEquals(FibonacciLoop.compute(i + 2), FibonacciLoop.compute(i + 1).add(FibonacciLoop.compute(i)));
+ }
+ }
+
+ @Test
+ public void checkNegativeInput() {
+ assertThrows(IllegalArgumentException.class, () -> { FibonacciLoop.compute(-1); });
+ }
+}
diff --git a/src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java b/src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java
new file mode 100644
index 000000000000..e3f7bf3e0fed
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java
@@ -0,0 +1,29 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.math.BigInteger;
+import org.junit.jupiter.api.Test;
+
+public class FibonacciNumberGoldenRationTest {
+
+ @Test
+ public void returnsCorrectValues() {
+ for (int n = 0; n <= FibonacciNumberGoldenRation.MAX_ARG; ++n) {
+ final var actual = FibonacciNumberGoldenRation.compute(n);
+ final var expected = FibonacciLoop.compute(n);
+ assertEquals(expected, BigInteger.valueOf(actual));
+ }
+ }
+
+ @Test
+ public void throwsIllegalArgumentExceptionForNegativeInput() {
+ assertThrows(IllegalArgumentException.class, () -> { FibonacciNumberGoldenRation.compute(-1); });
+ }
+
+ @Test
+ public void throwsIllegalArgumentExceptionForLargeInput() {
+ assertThrows(IllegalArgumentException.class, () -> { FibonacciNumberGoldenRation.compute(FibonacciNumberGoldenRation.MAX_ARG + 1); });
+ }
+}
From 48ae88f09d595bf6bdd3440b003e08419c885126 Mon Sep 17 00:00:00 2001
From: Lukas <142339568+lukasb1b@users.noreply.github.com>
Date: Sun, 15 Oct 2023 09:03:25 +0200
Subject: [PATCH 0053/1151] Bit swap (#4770)
* Create BitSwap.java
* Create BitSwapTest.java
* Update BitSwap.java
* Update BitSwap.java
* Update BitSwapTest.java
* Update BitSwap.java
* Update BitSwap.java
* Update BitSwapTest.java
* Update BitSwapTest.java
* Update src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update BitSwap.java
* Update BitSwap.java
* Update BitSwap.java
* Update src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* Update src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* style: remove redundant blank line
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../thealgorithms/bitmanipulation/BitSwap.java | 15 +++++++++++++++
.../bitmanipulation/BitSwapTest.java | 13 +++++++++++++
2 files changed, 28 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java
create mode 100644 src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java b/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java
new file mode 100644
index 000000000000..40b3097b1276
--- /dev/null
+++ b/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java
@@ -0,0 +1,15 @@
+package com.thealgorithms.bitmanipulation;
+
+public final class BitSwap {
+ private BitSwap() {
+ }
+ /*
+ * @brief Swaps the bits at the position posA and posB from data
+ */
+ public static int bitSwap(int data, final int posA, final int posB) {
+ if (SingleBitOperations.getBit(data, posA) != SingleBitOperations.getBit(data, posB)) {
+ data ^= (1 << posA) ^ (1 << posB);
+ }
+ return data;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java b/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java
new file mode 100644
index 000000000000..40de770e0c66
--- /dev/null
+++ b/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java
@@ -0,0 +1,13 @@
+package com.thealgorithms.bitmanipulation;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+public class BitSwapTest {
+ @Test
+ void testHighestSetBit() {
+ assertEquals(3, BitSwap.bitSwap(3, 0, 1));
+ assertEquals(5, BitSwap.bitSwap(6, 0, 1));
+ assertEquals(7, BitSwap.bitSwap(7, 1, 1));
+ }
+}
From 8002137b764de30918bfc1375fd816034edc3f16 Mon Sep 17 00:00:00 2001
From: Ayoub Chegraoui
Date: Sun, 15 Oct 2023 15:02:24 +0100
Subject: [PATCH 0054/1151] Fixed some typos and links for javadoc, and some
refactoring (#4755)
---
.../com/thealgorithms/ciphers/AESEncryption.java | 2 +-
.../thealgorithms/conversions/AnyBaseToDecimal.java | 2 +-
.../thealgorithms/conversions/DecimalToAnyBase.java | 2 +-
.../thealgorithms/conversions/RgbHsvConversion.java | 4 ++--
.../java/com/thealgorithms/geometry/GrahamScan.java | 12 +++++-------
5 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/src/main/java/com/thealgorithms/ciphers/AESEncryption.java b/src/main/java/com/thealgorithms/ciphers/AESEncryption.java
index 2b12aeaa0466..169fc10e5269 100644
--- a/src/main/java/com/thealgorithms/ciphers/AESEncryption.java
+++ b/src/main/java/com/thealgorithms/ciphers/AESEncryption.java
@@ -19,7 +19,7 @@ public class AESEncryption {
/**
* 1. Generate a plain text for encryption 2. Get a secret key (printed in
- * hexadecimal form). In actual use this must by encrypted and kept safe.
+ * hexadecimal form). In actual use this must be encrypted and kept safe.
* The same key is required for decryption.
*/
public static void main(String[] args) throws Exception {
diff --git a/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java b/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java
index 837b35305c80..20f15bc2ff39 100644
--- a/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java
+++ b/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java
@@ -1,7 +1,7 @@
package com.thealgorithms.conversions;
/**
- * @author Varun Upadhyay (https://github.com/varunu28)
+ * @author Varun Upadhyay (...)
*/
// Driver program
public class AnyBaseToDecimal {
diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java b/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java
index 31ef2bffb708..2d0223a4c448 100644
--- a/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java
+++ b/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java
@@ -5,7 +5,7 @@
import java.util.ArrayList;
/**
- * @author Varun Upadhyay (https://github.com/varunu28)
+ * @author Varun Upadhyay (...)
*/
// Driver Program
public class DecimalToAnyBase {
diff --git a/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java b/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java
index ca64c3ffd7a6..65cb00fc0ad0 100644
--- a/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java
+++ b/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java
@@ -10,8 +10,8 @@
* models how colors appear under light. In it, colors are represented using
* three components: hue, saturation and (brightness-)value. This class provides
* methods for converting colors from one representation to the other.
- * (description adapted from https://en.wikipedia.org/wiki/RGB_color_model and
- * https://en.wikipedia.org/wiki/HSL_and_HSV).
+ * (description adapted from [1] and
+ * [2]).
*/
public class RgbHsvConversion {
diff --git a/src/main/java/com/thealgorithms/geometry/GrahamScan.java b/src/main/java/com/thealgorithms/geometry/GrahamScan.java
index 3325a65829e0..9122c6f6f3cc 100644
--- a/src/main/java/com/thealgorithms/geometry/GrahamScan.java
+++ b/src/main/java/com/thealgorithms/geometry/GrahamScan.java
@@ -6,7 +6,7 @@
/*
* A Java program that computes the convex hull using the Graham Scan algorithm
- * In the best case, time complexity is O(n), while in the worst case, it is log(n).
+ * In the best case, time complexity is O(n), while in the worst case, it is O(nlog(n)).
* O(n) space complexity
*
* This algorithm is only applicable to integral coordinates.
@@ -106,16 +106,14 @@ public static int orientation(Point a, Point b, Point c) {
/**
* @param p2 Co-ordinate of point to compare to.
- * This function will compare the points and will return a positive integer it the
+ * This function will compare the points and will return a positive integer if the
* point is greater than the argument point and a negative integer if the point is
* less than the argument point.
*/
public int compareTo(Point p2) {
- if (this.y < p2.y) return -1;
- if (this.y > p2.y) return +1;
- if (this.x < p2.x) return -1;
- if (this.x > p2.x) return +1;
- return 0;
+ int res = Integer.compare(this.y, p2.y);
+ if (res == 0) res = Integer.compare(this.x, p2.x);
+ return res;
}
/**
From f3345d9e06dd39c730ad960ef6f4f8dbf73041b3 Mon Sep 17 00:00:00 2001
From: ironspec07 <127649008+ironspec07@users.noreply.github.com>
Date: Fri, 20 Oct 2023 00:32:27 +0530
Subject: [PATCH 0055/1151] Fixed typo error for better readability (#4835)
---
src/main/java/com/thealgorithms/misc/ColorContrastRatio.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java b/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java
index f7767d54a0aa..2d8371a9a53d 100644
--- a/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java
+++ b/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java
@@ -3,7 +3,7 @@
import java.awt.Color;
/**
- * @brief A Java implementation of the offcial W3 documented procedure to
+ * @brief A Java implementation of the official W3 documented procedure to
* calculate contrast ratio between colors on the web. This is used to calculate
* the readability of a foreground color on top of a background color.
* @since 2020-10-15
From e87036d886f2a3e477053bde76d5567f21615dd7 Mon Sep 17 00:00:00 2001
From: Aditi Bansal <142652964+Aditi22Bansal@users.noreply.github.com>
Date: Fri, 20 Oct 2023 01:07:29 +0530
Subject: [PATCH 0056/1151] Correct documentation of `IsEven` (#4845)
* Update IsEven.java
* Update IsEven.java
* Update IsEven.java
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
src/main/java/com/thealgorithms/bitmanipulation/IsEven.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java b/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java
index ec30eb09168b..b6bdc25fcc2b 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java
@@ -1,7 +1,7 @@
package com.thealgorithms.bitmanipulation;
/**
- * Converts any Octal Number to a Binary Number
+ * Checks whether a number is even
* @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
*/
From 9dae389faa03b8400b6f0796383f47495887151a Mon Sep 17 00:00:00 2001
From: Appari Satya Barghav <36763910+satyabarghav@users.noreply.github.com>
Date: Tue, 24 Oct 2023 02:39:42 +0530
Subject: [PATCH 0057/1151] Herons : Changed the signature of the function
(#4686)
* Made changes to the code to correct the Logic of Armstrong Number
* Resolved the issues
* Trying to resolve the Linter error by changing Variable name
* Changed Variable Names : trying to resolve Clang error
* Chnged the signature of the function
* Added the Function documentation
* Added exception for parameters
* Resolved with suggested changes
* Resolved with Suggested changes
* fix: use proper logic
---------
Co-authored-by: vil02
---
.../thealgorithms/maths/HeronsFormula.java | 35 ++++++++++++++-----
.../maths/HeronsFormulaTest.java | 20 ++++++++---
2 files changed, 42 insertions(+), 13 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/HeronsFormula.java b/src/main/java/com/thealgorithms/maths/HeronsFormula.java
index 72052a1b8d45..5baee715d1ec 100644
--- a/src/main/java/com/thealgorithms/maths/HeronsFormula.java
+++ b/src/main/java/com/thealgorithms/maths/HeronsFormula.java
@@ -1,18 +1,35 @@
package com.thealgorithms.maths;
/**
+ * Wikipedia for HeronsFormula => https://en.wikipedia.org/wiki/Heron%27s_formula
* Find the area of a triangle using only side lengths
*/
-public class HeronsFormula {
+public final class HeronsFormula {
- public static double Herons(int s1, int s2, int s3) {
- double a = s1;
- double b = s2;
- double c = s3;
- double s = (a + b + c) / 2.0;
- double area = 0;
- area = Math.sqrt((s) * (s - a) * (s - b) * (s - c));
- return area;
+ /*
+ * A function to get the Area of a Triangle using Heron's Formula
+ * @param s1,s2,s3 => the three sides of the Triangle
+ * @return area using the formula (√(s(s – s1)(s – s2)(s – s3)))
+ * here s is called semi-perimeter and it is the half of the perimeter (i.e; s = (s1+s2+s3)/2)
+ * @author satyabarghav
+ */
+ private HeronsFormula() {
+ }
+
+ private static boolean areAllSidesPositive(final double a, final double b, final double c) {
+ return a > 0 && b > 0 && c > 0;
+ }
+
+ private static boolean canFormTriangle(final double a, final double b, final double c) {
+ return a + b > c && b + c > a && c + a > b;
+ }
+
+ public static double herons(final double a, final double b, final double c) {
+ if (!areAllSidesPositive(a, b, c) || !canFormTriangle(a, b, c)) {
+ throw new IllegalArgumentException("Triangle can't be formed with the given side lengths");
+ }
+ final double s = (a + b + c) / 2.0;
+ return Math.sqrt((s) * (s - a) * (s - b) * (s - c));
}
}
diff --git a/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java b/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java
index 32feeacdb916..22cecf4dc960 100644
--- a/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java
+++ b/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java
@@ -7,21 +7,33 @@ public class HeronsFormulaTest {
@Test
void test1() {
- Assertions.assertEquals(HeronsFormula.Herons(3, 4, 5), 6.0);
+ Assertions.assertEquals(HeronsFormula.herons(3, 4, 5), 6.0);
}
@Test
void test2() {
- Assertions.assertEquals(HeronsFormula.Herons(24, 30, 18), 216.0);
+ Assertions.assertEquals(HeronsFormula.herons(24, 30, 18), 216.0);
}
@Test
void test3() {
- Assertions.assertEquals(HeronsFormula.Herons(1, 1, 1), 0.4330127018922193);
+ Assertions.assertEquals(HeronsFormula.herons(1, 1, 1), 0.4330127018922193);
}
@Test
void test4() {
- Assertions.assertEquals(HeronsFormula.Herons(4, 5, 8), 8.181534085976786);
+ Assertions.assertEquals(HeronsFormula.herons(4, 5, 8), 8.181534085976786);
+ }
+
+ @Test
+ public void testCalculateAreaWithInvalidInput() {
+ Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 2, 3); });
+ Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(2, 1, 3); });
+ Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(3, 2, 1); });
+ Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 3, 2); });
+
+ Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 1, 0); });
+ Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 0, 1); });
+ Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(0, 1, 1); });
}
}
From a4711d61d87cf75bf68f1f0b25345b1439220acf Mon Sep 17 00:00:00 2001
From: Aakil Iqbal <62759233+aakiliqbal@users.noreply.github.com>
Date: Wed, 25 Oct 2023 09:30:18 +0530
Subject: [PATCH 0058/1151] Added MapReduce Algorithm in Misc Folder. (#4828)
* Added MapReduce Algorithm in Misc Folder.
* Did formatting correctly
* Removed main function and added MapReduceTest
* format the code
---
.../com/thealgorithms/misc/MapReduce.java | 39 +++++++++++++++++++
.../com/thealgorithms/misc/MapReduceTest.java | 23 +++++++++++
2 files changed, 62 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/misc/MapReduce.java
create mode 100644 src/test/java/com/thealgorithms/misc/MapReduceTest.java
diff --git a/src/main/java/com/thealgorithms/misc/MapReduce.java b/src/main/java/com/thealgorithms/misc/MapReduce.java
new file mode 100644
index 000000000000..baf960f8ecef
--- /dev/null
+++ b/src/main/java/com/thealgorithms/misc/MapReduce.java
@@ -0,0 +1,39 @@
+package com.thealgorithms.misc;
+
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/*
+* MapReduce is a programming model for processing and generating large data sets with a parallel,
+distributed algorithm on a cluster.
+* It has two main steps: the Map step, where the data is divided into smaller chunks and processed in parallel,
+and the Reduce step, where the results from the Map step are combined to produce the final output.
+* Wikipedia link : https://en.wikipedia.org/wiki/MapReduce
+*/
+
+public class MapReduce {
+ /*
+ *Counting all the words frequency within a sentence.
+ */
+ public static String mapreduce(String sentence) {
+ List wordList = Arrays.stream(sentence.split(" ")).toList();
+
+ // Map step
+ Map wordCounts = wordList.stream().collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()));
+
+ // Reduce step
+ StringBuilder result = new StringBuilder();
+ wordCounts.forEach((word, count) -> result.append(word).append(": ").append(count).append(","));
+
+ // Removing the last ',' if it exists
+ if (!result.isEmpty()) {
+ result.setLength(result.length() - 1);
+ }
+
+ return result.toString();
+ }
+}
diff --git a/src/test/java/com/thealgorithms/misc/MapReduceTest.java b/src/test/java/com/thealgorithms/misc/MapReduceTest.java
new file mode 100644
index 000000000000..213acad9743b
--- /dev/null
+++ b/src/test/java/com/thealgorithms/misc/MapReduceTest.java
@@ -0,0 +1,23 @@
+package com.thealgorithms.misc;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class MapReduceTest {
+ @Test
+ public void testMapReduceWithSingleWordSentence() {
+ String oneWordSentence = "Hactober";
+ String result = MapReduce.mapreduce(oneWordSentence);
+
+ assertEquals("Hactober: 1", result);
+ }
+
+ @Test
+ public void testMapReduceWithMultipleWordSentence() {
+ String multipleWordSentence = "I Love Love HactoberFest";
+ String result = MapReduce.mapreduce(multipleWordSentence);
+
+ assertEquals("I: 1,Love: 2,HactoberFest: 1", result);
+ }
+}
From 9dde8a780832a29c508deb3382410e36f127fdf1 Mon Sep 17 00:00:00 2001
From: Anup Omkar <57665180+anupomkar@users.noreply.github.com>
Date: Wed, 25 Oct 2023 19:04:05 +0530
Subject: [PATCH 0059/1151] Add `MatrixRank` (#4571)
* feat: adding matrix rank algorithm
* fix: formatting
* fix: adding comments, refactor and handling edge cases
* refactor: minor refactor
* enhancement: check matrix validity
* refactor: minor refactor and fixes
* Update src/main/java/com/thealgorithms/maths/MatrixRank.java
* feat: add unit test to check if input matrix is not modified while calculating the rank
---------
Co-authored-by: Anup Omkar
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Co-authored-by: Andrii Siriak
---
.../com/thealgorithms/maths/MatrixRank.java | 164 ++++++++++++++++++
.../thealgorithms/maths/MatrixRankTest.java | 45 +++++
2 files changed, 209 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/maths/MatrixRank.java
create mode 100644 src/test/java/com/thealgorithms/maths/MatrixRankTest.java
diff --git a/src/main/java/com/thealgorithms/maths/MatrixRank.java b/src/main/java/com/thealgorithms/maths/MatrixRank.java
new file mode 100644
index 000000000000..7a628b92dccb
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/MatrixRank.java
@@ -0,0 +1,164 @@
+package com.thealgorithms.maths;
+
+/**
+ * This class provides a method to compute the rank of a matrix.
+ * In linear algebra, the rank of a matrix is the maximum number of linearly independent rows or columns in the matrix.
+ * For example, consider the following 3x3 matrix:
+ * 1 2 3
+ * 2 4 6
+ * 3 6 9
+ * Despite having 3 rows and 3 columns, this matrix only has a rank of 1 because all rows (and columns) are multiples of each other.
+ * It's a fundamental concept that gives key insights into the structure of the matrix.
+ * It's important to note that the rank is not only defined for square matrices but for any m x n matrix.
+ *
+ * @author Anup Omkar
+ */
+public final class MatrixRank {
+
+ private MatrixRank() {
+ }
+
+ private static final double EPSILON = 1e-10;
+
+ /**
+ * @brief Computes the rank of the input matrix
+ *
+ * @param matrix The input matrix
+ * @return The rank of the input matrix
+ */
+ public static int computeRank(double[][] matrix) {
+ validateInputMatrix(matrix);
+
+ int numRows = matrix.length;
+ int numColumns = matrix[0].length;
+ int rank = 0;
+
+ boolean[] rowMarked = new boolean[numRows];
+
+ double[][] matrixCopy = deepCopy(matrix);
+
+ for (int colIndex = 0; colIndex < numColumns; ++colIndex) {
+ int pivotRow = findPivotRow(matrixCopy, rowMarked, colIndex);
+ if (pivotRow != numRows) {
+ ++rank;
+ rowMarked[pivotRow] = true;
+ normalizePivotRow(matrixCopy, pivotRow, colIndex);
+ eliminateRows(matrixCopy, pivotRow, colIndex);
+ }
+ }
+ return rank;
+ }
+
+ private static boolean isZero(double value) {
+ return Math.abs(value) < EPSILON;
+ }
+
+ private static double[][] deepCopy(double[][] matrix) {
+ int numRows = matrix.length;
+ int numColumns = matrix[0].length;
+ double[][] matrixCopy = new double[numRows][numColumns];
+ for (int rowIndex = 0; rowIndex < numRows; ++rowIndex) {
+ System.arraycopy(matrix[rowIndex], 0, matrixCopy[rowIndex], 0, numColumns);
+ }
+ return matrixCopy;
+ }
+
+ private static void validateInputMatrix(double[][] matrix) {
+ if (matrix == null) {
+ throw new IllegalArgumentException("The input matrix cannot be null");
+ }
+ if (matrix.length == 0) {
+ throw new IllegalArgumentException("The input matrix cannot be empty");
+ }
+ if (!hasValidRows(matrix)) {
+ throw new IllegalArgumentException("The input matrix cannot have null or empty rows");
+ }
+ if (isJaggedMatrix(matrix)) {
+ throw new IllegalArgumentException("The input matrix cannot be jagged");
+ }
+ }
+
+ private static boolean hasValidRows(double[][] matrix) {
+ for (double[] row : matrix) {
+ if (row == null || row.length == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @brief Checks if the input matrix is a jagged matrix.
+ * Jagged matrix is a matrix where the number of columns in each row is not the same.
+ *
+ * @param matrix The input matrix
+ * @return True if the input matrix is a jagged matrix, false otherwise
+ */
+ private static boolean isJaggedMatrix(double[][] matrix) {
+ int numColumns = matrix[0].length;
+ for (double[] row : matrix) {
+ if (row.length != numColumns) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @brief The pivot row is the row in the matrix that is used to eliminate other rows and reduce the matrix to its row echelon form.
+ * The pivot row is selected as the first row (from top to bottom) where the value in the current column (the pivot column) is not zero.
+ * This row is then used to "eliminate" other rows, by subtracting multiples of the pivot row from them, so that all other entries in the pivot column become zero.
+ * This process is repeated for each column, each time selecting a new pivot row, until the matrix is in row echelon form.
+ * The number of pivot rows (rows with a leading entry, or pivot) then gives the rank of the matrix.
+ *
+ * @param matrix The input matrix
+ * @param rowMarked An array indicating which rows have been marked
+ * @param colIndex The column index
+ * @return The pivot row index, or the number of rows if no suitable pivot row was found
+ */
+ private static int findPivotRow(double[][] matrix, boolean[] rowMarked, int colIndex) {
+ int numRows = matrix.length;
+ for (int pivotRow = 0; pivotRow < numRows; ++pivotRow) {
+ if (!rowMarked[pivotRow] && !isZero(matrix[pivotRow][colIndex])) {
+ return pivotRow;
+ }
+ }
+ return numRows;
+ }
+
+ /**
+ * @brief This method divides all values in the pivot row by the value in the given column.
+ * This ensures that the pivot value itself will be 1, which simplifies further calculations.
+ *
+ * @param matrix The input matrix
+ * @param pivotRow The pivot row index
+ * @param colIndex The column index
+ */
+ private static void normalizePivotRow(double[][] matrix, int pivotRow, int colIndex) {
+ int numColumns = matrix[0].length;
+ for (int nextCol = colIndex + 1; nextCol < numColumns; ++nextCol) {
+ matrix[pivotRow][nextCol] /= matrix[pivotRow][colIndex];
+ }
+ }
+
+ /**
+ * @brief This method subtracts multiples of the pivot row from all other rows,
+ * so that all values in the given column of other rows will be zero.
+ * This is a key step in reducing the matrix to row echelon form.
+ *
+ * @param matrix The input matrix
+ * @param pivotRow The pivot row index
+ * @param colIndex The column index
+ */
+ private static void eliminateRows(double[][] matrix, int pivotRow, int colIndex) {
+ int numRows = matrix.length;
+ int numColumns = matrix[0].length;
+ for (int otherRow = 0; otherRow < numRows; ++otherRow) {
+ if (otherRow != pivotRow && !isZero(matrix[otherRow][colIndex])) {
+ for (int col2 = colIndex + 1; col2 < numColumns; ++col2) {
+ matrix[otherRow][col2] -= matrix[pivotRow][col2] * matrix[otherRow][colIndex];
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/maths/MatrixRankTest.java b/src/test/java/com/thealgorithms/maths/MatrixRankTest.java
new file mode 100644
index 000000000000..415b84ec43f8
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/MatrixRankTest.java
@@ -0,0 +1,45 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Arrays;
+import java.util.stream.Stream;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class MatrixRankTest {
+
+ private static Stream validInputStream() {
+ return Stream.of(Arguments.of(3, new double[][] {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}), Arguments.of(0, new double[][] {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}), Arguments.of(1, new double[][] {{1}}), Arguments.of(2, new double[][] {{1, 2}, {3, 4}}),
+ Arguments.of(2, new double[][] {{3, -1, 2}, {-3, 1, 2}, {-6, 2, 4}}), Arguments.of(3, new double[][] {{2, 3, 0, 1}, {1, 0, 1, 2}, {-1, 1, 1, -2}, {1, 5, 3, -1}}), Arguments.of(1, new double[][] {{1, 2, 3}, {3, 6, 9}}),
+ Arguments.of(2, new double[][] {{0.25, 0.5, 0.75, 2}, {1.5, 3, 4.5, 6}, {1, 2, 3, 4}}));
+ }
+
+ private static Stream invalidInputStream() {
+ return Stream.of(Arguments.of((Object) new double[][] {{1, 2}, {10}, {100, 200, 300}}), // jagged array
+ Arguments.of((Object) new double[][] {}), // empty matrix
+ Arguments.of((Object) new double[][] {{}, {}}), // empty row
+ Arguments.of((Object) null), // null matrix
+ Arguments.of((Object) new double[][] {{1, 2}, null}) // null row
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("validInputStream")
+ void computeRankTests(int expectedRank, double[][] matrix) {
+ int originalHashCode = Arrays.deepHashCode(matrix);
+ int rank = MatrixRank.computeRank(matrix);
+ int newHashCode = Arrays.deepHashCode(matrix);
+
+ assertEquals(expectedRank, rank);
+ assertEquals(originalHashCode, newHashCode);
+ }
+
+ @ParameterizedTest
+ @MethodSource("invalidInputStream")
+ void computeRankWithInvalidMatrix(double[][] matrix) {
+ assertThrows(IllegalArgumentException.class, () -> MatrixRank.computeRank(matrix));
+ }
+}
From 945e7b56bb186c3be908e02720e932b5ce834e01 Mon Sep 17 00:00:00 2001
From: Satvik Singh Sengar
Date: Mon, 30 Oct 2023 22:54:23 +0530
Subject: [PATCH 0060/1151] Fix:/Number of count of major element in Boyer
Moore algorithm (#4728)
* Number of count of major element in Boyer Moore algorithm
* test: add `BoyerMooreTest`
* style: basic linting
* tests: add test case from the issue
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Co-authored-by: vil02
---
.../com/thealgorithms/others/BoyerMoore.java | 30 +++++++------------
.../thealgorithms/others/BoyerMooreTest.java | 22 ++++++++++++++
2 files changed, 32 insertions(+), 20 deletions(-)
create mode 100644 src/test/java/com/thealgorithms/others/BoyerMooreTest.java
diff --git a/src/main/java/com/thealgorithms/others/BoyerMoore.java b/src/main/java/com/thealgorithms/others/BoyerMoore.java
index 09235b521b44..d9d5b5d028ef 100644
--- a/src/main/java/com/thealgorithms/others/BoyerMoore.java
+++ b/src/main/java/com/thealgorithms/others/BoyerMoore.java
@@ -6,27 +6,28 @@
*/
package com.thealgorithms.others;
-import java.util.*;
-
-public class BoyerMoore {
+public final class BoyerMoore {
+ private BoyerMoore() {
+ }
- public static int findmajor(int[] a) {
+ public static int findmajor(final int[] a) {
int count = 0;
int cand = -1;
- for (int i = 0; i < a.length; i++) {
+ for (final var k : a) {
if (count == 0) {
- cand = a[i];
+ cand = k;
count = 1;
} else {
- if (a[i] == cand) {
+ if (k == cand) {
count++;
} else {
count--;
}
}
}
- for (int i = 0; i < a.length; i++) {
- if (a[i] == cand) {
+ count = 0;
+ for (final var j : a) {
+ if (j == cand) {
count++;
}
}
@@ -35,15 +36,4 @@ public static int findmajor(int[] a) {
}
return -1;
}
-
- public static void main(String[] args) {
- Scanner input = new Scanner(System.in);
- int n = input.nextInt();
- int[] a = new int[n];
- for (int i = 0; i < n; i++) {
- a[i] = input.nextInt();
- }
- System.out.println("the majority element is " + findmajor(a));
- input.close();
- }
}
diff --git a/src/test/java/com/thealgorithms/others/BoyerMooreTest.java b/src/test/java/com/thealgorithms/others/BoyerMooreTest.java
new file mode 100644
index 000000000000..b614c14070bd
--- /dev/null
+++ b/src/test/java/com/thealgorithms/others/BoyerMooreTest.java
@@ -0,0 +1,22 @@
+package com.thealgorithms.others;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class BoyerMooreTest {
+
+ @ParameterizedTest
+ @MethodSource("inputStream")
+ void numberTests(int expected, int[] input) {
+ Assertions.assertEquals(expected, BoyerMoore.findmajor(input));
+ }
+
+ private static Stream inputStream() {
+ return Stream.of(Arguments.of(5, new int[] {5, 5, 5, 2}), Arguments.of(10, new int[] {10, 10, 20}), Arguments.of(10, new int[] {10, 20, 10}), Arguments.of(10, new int[] {20, 10, 10}), Arguments.of(-1, new int[] {10, 10, 20, 20, 30, 30}), Arguments.of(4, new int[] {1, 4, 2, 4, 4, 5, 4}));
+ }
+}
From e5f3d232c9fb97ed350a57708fc29d30fa0b28ae Mon Sep 17 00:00:00 2001
From: Phuong Nguyen
Date: Tue, 31 Oct 2023 05:09:43 +0700
Subject: [PATCH 0061/1151] refactor: use method `SortUtils.swap` (#4946)
* refactor: use method SortUtils.swap
* fix: clang format
* style: explicitly import `swap`
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
src/main/java/com/thealgorithms/sorts/SelectionSort.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/main/java/com/thealgorithms/sorts/SelectionSort.java b/src/main/java/com/thealgorithms/sorts/SelectionSort.java
index 555b4b6037dc..e43df7fe622e 100644
--- a/src/main/java/com/thealgorithms/sorts/SelectionSort.java
+++ b/src/main/java/com/thealgorithms/sorts/SelectionSort.java
@@ -1,5 +1,7 @@
package com.thealgorithms.sorts;
+import static com.thealgorithms.sorts.SortUtils.swap;
+
public class SelectionSort implements SortAlgorithm {
/**
@@ -20,9 +22,7 @@ public > T[] sort(T[] arr) {
}
}
if (minIndex != i) {
- T temp = arr[i];
- arr[i] = arr[minIndex];
- arr[minIndex] = temp;
+ swap(arr, i, minIndex);
}
}
return arr;
From d086afce09a7de8d64332cc41015d3cf00e90cee Mon Sep 17 00:00:00 2001
From: Hardik Pawar <97388607+Hardvan@users.noreply.github.com>
Date: Tue, 31 Oct 2023 03:48:05 +0530
Subject: [PATCH 0062/1151] Enhance code density and readability (#4914)
* Enhance code density and readability
* Add wiki link
---------
Co-authored-by: vil02 <65706193+vil02@users.noreply.github.com>
---
.../divideandconquer/BinaryExponentiation.java | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java b/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java
index da45d5b90cae..a70b16b0d069 100644
--- a/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java
+++ b/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java
@@ -2,6 +2,8 @@
// Java Program to Implement Binary Exponentiation (power in log n)
+// Reference Link: https://en.wikipedia.org/wiki/Exponentiation_by_squaring
+
/*
* Binary Exponentiation is a method to calculate a to the power of b.
* It is used to calculate a^n in O(log n) time.
@@ -14,14 +16,14 @@ public class BinaryExponentiation {
// recursive function to calculate a to the power of b
public static long calculatePower(long x, long y) {
+ // Base Case
if (y == 0) {
return 1;
}
- long val = calculatePower(x, y / 2);
- if (y % 2 == 0) {
- return val * val;
+ if (y % 2 == 1) { // odd power
+ return x * calculatePower(x, y - 1);
}
- return val * val * x;
+ return calculatePower(x * x, y / 2); // even power
}
// iterative function to calculate a to the power of b
From 574138c7a35351a0837bb4bd56e2eb295064b690 Mon Sep 17 00:00:00 2001
From: Prathamesh Powar
Date: Tue, 31 Oct 2023 13:37:59 +0530
Subject: [PATCH 0063/1151] Cleanup `BoyerMoore` (#4951)
* modify code to make use of java Optional class
* revert changes
* add java.util.Optional
* add java.util.Optional
* refactors: make `findmajor` return `optional`
* refactors: make method name findMajor and split it
* refactors: change method name in tests
* Apply suggestions from code review
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
* change back to int
* fix: swap arguments
* tests: add some test cases
* refactor: add `isMajority` and avoid rounding
* style: use `var`
* style: swap arguments of `countOccurrences`
---------
Co-authored-by: vil02
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../com/thealgorithms/others/BoyerMoore.java | 35 +++++++++++++------
.../thealgorithms/others/BoyerMooreTest.java | 20 ++++++++---
2 files changed, 40 insertions(+), 15 deletions(-)
diff --git a/src/main/java/com/thealgorithms/others/BoyerMoore.java b/src/main/java/com/thealgorithms/others/BoyerMoore.java
index d9d5b5d028ef..e67427deda79 100644
--- a/src/main/java/com/thealgorithms/others/BoyerMoore.java
+++ b/src/main/java/com/thealgorithms/others/BoyerMoore.java
@@ -5,35 +5,50 @@
https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm
*/
package com.thealgorithms.others;
+import java.util.Optional;
public final class BoyerMoore {
private BoyerMoore() {
}
- public static int findmajor(final int[] a) {
+ public static Optional findMajor(final int[] a) {
+ final var candidate = findCandidate(a);
+ final var count = countOccurrences(candidate, a);
+ if (isMajority(count, a.length)) {
+ return Optional.of(candidate);
+ }
+ return Optional.empty();
+ }
+
+ private static int findCandidate(final int[] a) {
int count = 0;
- int cand = -1;
+ int candidate = -1;
for (final var k : a) {
if (count == 0) {
- cand = k;
+ candidate = k;
count = 1;
} else {
- if (k == cand) {
+ if (k == candidate) {
count++;
} else {
count--;
}
}
}
- count = 0;
+ return candidate;
+ }
+
+ private static int countOccurrences(final int candidate, final int[] a) {
+ int count = 0;
for (final var j : a) {
- if (j == cand) {
+ if (j == candidate) {
count++;
}
}
- if (count > (a.length / 2)) {
- return cand;
- }
- return -1;
+ return count;
+ }
+
+ private static boolean isMajority(final int count, final int totalCount) {
+ return 2 * count > totalCount;
}
}
diff --git a/src/test/java/com/thealgorithms/others/BoyerMooreTest.java b/src/test/java/com/thealgorithms/others/BoyerMooreTest.java
index b614c14070bd..b1497f7bc525 100644
--- a/src/test/java/com/thealgorithms/others/BoyerMooreTest.java
+++ b/src/test/java/com/thealgorithms/others/BoyerMooreTest.java
@@ -11,12 +11,22 @@
public class BoyerMooreTest {
@ParameterizedTest
- @MethodSource("inputStream")
- void numberTests(int expected, int[] input) {
- Assertions.assertEquals(expected, BoyerMoore.findmajor(input));
+ @MethodSource("inputStreamWithExistingMajority")
+ void checkWhenMajorityExists(int expected, int[] input) {
+ Assertions.assertEquals(expected, BoyerMoore.findMajor(input).get());
}
- private static Stream inputStream() {
- return Stream.of(Arguments.of(5, new int[] {5, 5, 5, 2}), Arguments.of(10, new int[] {10, 10, 20}), Arguments.of(10, new int[] {10, 20, 10}), Arguments.of(10, new int[] {20, 10, 10}), Arguments.of(-1, new int[] {10, 10, 20, 20, 30, 30}), Arguments.of(4, new int[] {1, 4, 2, 4, 4, 5, 4}));
+ private static Stream inputStreamWithExistingMajority() {
+ return Stream.of(Arguments.of(5, new int[] {5, 5, 5, 2}), Arguments.of(10, new int[] {10, 10, 20}), Arguments.of(10, new int[] {10, 20, 10}), Arguments.of(10, new int[] {20, 10, 10}), Arguments.of(4, new int[] {1, 4, 2, 4, 4, 5, 4}), Arguments.of(-1, new int[] {-1}));
+ }
+
+ @ParameterizedTest
+ @MethodSource("inputStreamWithoutMajority")
+ void checkWhenMajorityExists(int[] input) {
+ Assertions.assertFalse(BoyerMoore.findMajor(input).isPresent());
+ }
+
+ private static Stream inputStreamWithoutMajority() {
+ return Stream.of(Arguments.of(new int[] {10, 10, 20, 20, 30, 30}), Arguments.of(new int[] {10, 20, 30, 40, 50}), Arguments.of(new int[] {1, 2}), Arguments.of(new int[] {}));
}
}
From c527dff92da2046b850ffe9a3b8d0c2aae15d588 Mon Sep 17 00:00:00 2001
From: "D.Sunil"
Date: Sun, 12 Nov 2023 02:25:48 +0530
Subject: [PATCH 0064/1151] Add Javadoc comments (#4745)
---
.../dynamicprogramming/RodCutting.java | 37 +++++++++++--------
1 file changed, 21 insertions(+), 16 deletions(-)
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java b/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java
index 28ff41d1a2d1..4583aec2e1b4 100644
--- a/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java
@@ -1,32 +1,37 @@
package com.thealgorithms.dynamicprogramming;
/**
- * A DynamicProgramming solution for Rod cutting problem Returns the best
- * obtainable price for a rod of length n and price[] as prices of different
- * pieces
+ * A Dynamic Programming solution for the Rod cutting problem.
+ * Returns the best obtainable price for a rod of length n and price[] as prices of different pieces.
*/
public class RodCutting {
- private static int cutRod(int[] price, int n) {
+ /**
+ * This method calculates the maximum obtainable value for cutting a rod of length n
+ * into different pieces, given the prices for each possible piece length.
+ *
+ * @param price An array representing the prices of different pieces, where price[i-1]
+ * represents the price of a piece of length i.
+ * @param n The length of the rod to be cut.
+ * @return The maximum obtainable value.
+ */
+ public static int cutRod(int[] price, int n) {
+ // Create an array to store the maximum obtainable values for each rod length.
int[] val = new int[n + 1];
val[0] = 0;
+ // Calculate the maximum value for each rod length from 1 to n.
for (int i = 1; i <= n; i++) {
- int max_val = Integer.MIN_VALUE;
- for (int j = 0; j < i; j++) {
- max_val = Math.max(max_val, price[j] + val[i - j - 1]);
+ int maxVal = Integer.MIN_VALUE;
+ // Try all possible ways to cut the rod and find the maximum value.
+ for (int j = 1; j <= i; j++) {
+ maxVal = Math.max(maxVal, price[j - 1] + val[i - j]);
}
-
- val[i] = max_val;
+ // Store the maximum value for the current rod length.
+ val[i] = maxVal;
}
+ // The final element of 'val' contains the maximum obtainable value for a rod of length 'n'.
return val[n];
}
-
- // main function to test
- public static void main(String[] args) {
- int[] arr = new int[] {2, 5, 13, 19, 20};
- int result = cutRod(arr, arr.length);
- System.out.println("Maximum Obtainable Value is " + result);
- }
}
From b1efd4e34bb18a618ab205c9c2a62802f151c70d Mon Sep 17 00:00:00 2001
From: Niklas Hoefflin <122729995+itakurah@users.noreply.github.com>
Date: Fri, 24 Nov 2023 18:13:44 +0100
Subject: [PATCH 0065/1151] Add G-Counter (Grow-only Counter) (#4965)
---
.../datastructures/crdt/GCounter.java | 84 +++++++++++++++++++
.../datastructures/crdt/GCounterTest.java | 54 ++++++++++++
2 files changed, 138 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java
create mode 100644 src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java
diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java b/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java
new file mode 100644
index 000000000000..63364f858ec5
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java
@@ -0,0 +1,84 @@
+package com.thealgorithms.datastructures.crdt;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * G-Counter (Grow-only Counter) is a state-based CRDT (Conflict-free Replicated Data Type)
+ * designed for tracking counts in a distributed and concurrent environment.
+ * Each process maintains its own counter, allowing only increments. The total count
+ * is obtained by summing individual process counts.
+ * This implementation supports incrementing, querying the total count,
+ * comparing with other G-Counters, and merging with another G-Counter
+ * to compute the element-wise maximum.
+ * (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type)
+ *
+ * @author itakurah (https://github.com/itakurah)
+ */
+
+class GCounter {
+ private final Map P;
+ private final int myId;
+ private final int n;
+
+ /**
+ * Constructs a G-Counter for a cluster of n nodes.
+ *
+ * @param n The number of nodes in the cluster.
+ */
+ public GCounter(int myId, int n) {
+ this.myId = myId;
+ this.n = n;
+ this.P = new HashMap<>();
+
+ for (int i = 0; i < n; i++) {
+ P.put(i, 0);
+ }
+ }
+
+ /**
+ * Increments the counter for the current node.
+ */
+ public void increment() {
+ P.put(myId, P.get(myId) + 1);
+ }
+
+ /**
+ * Gets the total value of the counter by summing up values from all nodes.
+ *
+ * @return The total value of the counter.
+ */
+ public int value() {
+ int sum = 0;
+ for (int v : P.values()) {
+ sum += v;
+ }
+ return sum;
+ }
+
+ /**
+ * Compares the state of this G-Counter with another G-Counter.
+ *
+ * @param other The other G-Counter to compare with.
+ * @return True if the state of this G-Counter is less than or equal to the state of the other G-Counter.
+ */
+ public boolean compare(GCounter other) {
+ for (int i = 0; i < n; i++) {
+ if (this.P.get(i) > other.P.get(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Merges the state of this G-Counter with another G-Counter.
+ *
+ * @param other The other G-Counter to merge with.
+ */
+ public void merge(GCounter other) {
+ for (int i = 0; i < n; i++) {
+ this.P.put(i, Math.max(this.P.get(i), other.P.get(i)));
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java
new file mode 100644
index 000000000000..f931e602383c
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java
@@ -0,0 +1,54 @@
+package com.thealgorithms.datastructures.crdt;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class GCounterTest {
+ @Test
+ void increment() {
+ GCounter counter = new GCounter(0, 3);
+ counter.increment();
+ counter.increment();
+ counter.increment();
+ assertEquals(3, counter.value());
+ }
+
+ @Test
+ void merge() {
+ GCounter counter1 = new GCounter(0, 3);
+ counter1.increment();
+ GCounter counter2 = new GCounter(1, 3);
+ counter2.increment();
+ counter2.increment();
+ GCounter counter3 = new GCounter(2, 3);
+ counter3.increment();
+ counter3.increment();
+ counter3.increment();
+ counter1.merge(counter2);
+ counter1.merge(counter3);
+ counter2.merge(counter1);
+ counter3.merge(counter2);
+ assertEquals(6, counter1.value());
+ assertEquals(6, counter2.value());
+ assertEquals(6, counter3.value());
+ }
+
+ @Test
+ void compare() {
+ GCounter counter1 = new GCounter(0, 5);
+ GCounter counter2 = new GCounter(3, 5);
+ counter1.increment();
+ counter1.increment();
+ counter2.merge(counter1);
+ counter2.increment();
+ counter2.increment();
+ assertTrue(counter1.compare(counter2));
+ counter1.increment();
+ counter2.increment();
+ counter2.merge(counter1);
+ assertTrue(counter1.compare(counter2));
+ counter1.increment();
+ assertFalse(counter1.compare(counter2));
+ }
+}
From 1518e84fb961f988b35ef402ec25a6576879c7ff Mon Sep 17 00:00:00 2001
From: Doksanbir
Date: Sun, 26 Nov 2023 14:34:13 +0300
Subject: [PATCH 0066/1151] Add Tribonacci Numbers (fixes #4646) (#4959)
---
.../dynamicprogramming/Tribonacci.java | 30 +++++++++++++++++++
.../dynamicprogramming/TribonacciTest.java | 24 +++++++++++++++
2 files changed, 54 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java
create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java b/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java
new file mode 100644
index 000000000000..99f9029009ab
--- /dev/null
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java
@@ -0,0 +1,30 @@
+package com.thealgorithms.dynamicprogramming;
+
+/**
+ * The {@code Tribonacci} class provides a method to compute the n-th number in the Tribonacci sequence.
+ * N-th Tribonacci Number - https://leetcode.com/problems/n-th-tribonacci-number/description/
+ */
+public class Tribonacci {
+
+ /**
+ * Computes the n-th Tribonacci number.
+ *
+ * @param n the index of the Tribonacci number to compute
+ * @return the n-th Tribonacci number
+ */
+ public static int compute(int n) {
+ if (n == 0) return 0;
+ if (n == 1 || n == 2) return 1;
+
+ int first = 0, second = 1, third = 1;
+
+ for (int i = 3; i <= n; i++) {
+ int next = first + second + third;
+ first = second;
+ second = third;
+ third = next;
+ }
+
+ return third;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java
new file mode 100644
index 000000000000..434a1825dfec
--- /dev/null
+++ b/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java
@@ -0,0 +1,24 @@
+package com.thealgorithms.dynamicprogramming;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test class for {@code Tribonacci}.
+ */
+public class TribonacciTest {
+
+ /**
+ * Tests the Tribonacci computation for a set of known values.
+ */
+ @Test
+ public void testKnownValues() {
+ assertEquals(0, Tribonacci.compute(0), "The 0th Tribonacci should be 0.");
+ assertEquals(1, Tribonacci.compute(1), "The 1st Tribonacci should be 1.");
+ assertEquals(1, Tribonacci.compute(2), "The 2nd Tribonacci should be 1.");
+ assertEquals(2, Tribonacci.compute(3), "The 3rd Tribonacci should be 2.");
+ assertEquals(4, Tribonacci.compute(4), "The 4th Tribonacci should be 4.");
+ assertEquals(7, Tribonacci.compute(5), "The 5th Tribonacci should be 7.");
+ }
+}
From 3392b5116dc79f876a275539ec099b3d3a6894c6 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Tue, 28 Nov 2023 21:40:51 +0100
Subject: [PATCH 0067/1151] Add `codeql.yml` (#4966)
---
.github/workflows/codeql.yml | 47 ++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 .github/workflows/codeql.yml
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 000000000000..482c8bc60527
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,47 @@
+---
+name: "CodeQL"
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - master
+ pull_request:
+ schedule:
+ - cron: '53 3 * * 0'
+
+env:
+ LANGUAGE: 'java-kotlin'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: 'ubuntu-latest'
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v3
+ with:
+ java-version: 17
+ distribution: 'adopt'
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ with:
+ languages: ${{ env.LANGUAGE }}
+
+ - name: Build
+ run: mvn --batch-mode --update-snapshots verify
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
+ with:
+ category: "/language:${{env.LANGUAGE}}"
+...
From 361b4108ee0ae7f5e5fde95121d4d5d91eae5c6a Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Wed, 29 Nov 2023 22:21:25 +0100
Subject: [PATCH 0068/1151] Use explicit cast to `int` in `FractionalKnapsack`
(#4971)
---
.../com/thealgorithms/greedyalgorithms/FractionalKnapsack.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java b/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java
index c5570f35c004..f46364fc704b 100644
--- a/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java
+++ b/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java
@@ -32,7 +32,7 @@ public static int fractionalKnapsack(int weight[], int value[], int capacity) {
current -= weight[index];
} else {
// If only a fraction of the item can fit, add a proportionate value.
- finalValue += ratio[i][1] * current;
+ finalValue += (int) (ratio[i][1] * current);
break; // Stop adding items to the knapsack since it's full.
}
}
From f8de2901887a360ac3d2901b523f6b7e4df65e54 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Wed, 29 Nov 2023 22:30:59 +0100
Subject: [PATCH 0069/1151] Explicitly cast result of `Math.pow` to `int` in
`BinaryToHexadecimal` (#4970)
---
.../java/com/thealgorithms/conversions/BinaryToHexadecimal.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java b/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java
index c942cbb7d843..011b60a952b8 100644
--- a/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java
+++ b/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java
@@ -34,7 +34,7 @@ static String binToHex(int binary) {
for (i = 0; i < 4; i++) {
currbit = binary % 10;
binary = binary / 10;
- code4 += currbit * Math.pow(2, i);
+ code4 += currbit * (int) Math.pow(2, i);
}
hex = hm.get(code4) + hex;
}
From fc21a8bffe4398ba059c76f7968f43d150985103 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Thu, 30 Nov 2023 09:50:09 +0100
Subject: [PATCH 0070/1151] Explicitly cast result of `Math.pow` to `long` in
`Armstrong` (#4972)
---
src/main/java/com/thealgorithms/maths/Armstrong.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/thealgorithms/maths/Armstrong.java b/src/main/java/com/thealgorithms/maths/Armstrong.java
index 526b31c3891f..ff4ae027a0b7 100644
--- a/src/main/java/com/thealgorithms/maths/Armstrong.java
+++ b/src/main/java/com/thealgorithms/maths/Armstrong.java
@@ -27,7 +27,7 @@ public boolean isArmstrong(int number) {
while (originalNumber > 0) {
long digit = originalNumber % 10;
- sum += Math.pow(digit, power); // The digit raised to the power of the number of digits and added to the sum.
+ sum += (long) Math.pow(digit, power); // The digit raised to the power of the number of digits and added to the sum.
originalNumber /= 10;
}
From 9bebcee5c795dfc675196803b7d987ca3e4f9025 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Thu, 30 Nov 2023 17:36:31 +0100
Subject: [PATCH 0071/1151] Make `sumOfDigits` `long` in
`HarshadNumber.isHarshad` (#4973)
fix: make `sumOfDigits` `long` in `HarshadNumber.isHarshad`
---
src/main/java/com/thealgorithms/maths/HarshadNumber.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/thealgorithms/maths/HarshadNumber.java b/src/main/java/com/thealgorithms/maths/HarshadNumber.java
index 854e4d555b40..4778dc81b664 100644
--- a/src/main/java/com/thealgorithms/maths/HarshadNumber.java
+++ b/src/main/java/com/thealgorithms/maths/HarshadNumber.java
@@ -15,7 +15,7 @@ public static boolean isHarshad(long n) {
if (n <= 0) return false;
long t = n;
- int sumOfDigits = 0;
+ long sumOfDigits = 0;
while (t > 0) {
sumOfDigits += t % 10;
t /= 10;
From e759544c333de9b98ff51458e1d71c69006f976b Mon Sep 17 00:00:00 2001
From: Niklas Hoefflin <122729995+itakurah@users.noreply.github.com>
Date: Sat, 2 Dec 2023 18:53:17 +0100
Subject: [PATCH 0072/1151] Add Boruvka's algorithm to find Minimum Spanning
Tree (#4964)
---
DIRECTORY.md | 20 ++
.../graphs/BoruvkaAlgorithm.java | 217 ++++++++++++++++++
.../graphs/BoruvkaAlgorithmTest.java | 191 +++++++++++++++
3 files changed, 428 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java
create mode 100644 src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 6de516618484..89f08c27248b 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -19,6 +19,7 @@
* [PowerSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/PowerSum.java)
* [WordSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/WordSearch.java)
* bitmanipulation
+ * [BitSwap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java)
* [HighestSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java)
* [IndexOfRightMostSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java)
* [IsEven](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java)
@@ -81,6 +82,8 @@
* [LFUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java)
* [LRUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java)
* [MRUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java)
+ * crdt
+ * [GCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java)
* disjointsetunion
* [DisjointSetUnion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java)
* [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java)
@@ -90,6 +93,7 @@
* [A Star](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java)
* [BellmanFord](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java)
* [BipartiteGrapfDFS](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java)
+ * [BoruvkaAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java)
* [ConnectedComponent](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java)
* [Cycles](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java)
* [DIJSKSTRAS ALGORITHM](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java)
@@ -239,6 +243,7 @@
* [SubsetCount](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java)
* [SubsetSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java)
* [Sum Of Subset](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Sum_Of_Subset.java)
+ * [Tribonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java)
* [UniquePaths](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java)
* [WildcardMatching](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java)
* [WineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java)
@@ -281,7 +286,9 @@
* [FFT](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FFT.java)
* [FFTBluestein](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FFTBluestein.java)
* [FibonacciJavaStreams](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java)
+ * [FibonacciLoop](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciLoop.java)
* [FibonacciNumberCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java)
+ * [FibonacciNumberGoldenRation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java)
* [FindKthNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindKthNumber.java)
* [FindMax](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindMax.java)
* [FindMaxRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java)
@@ -307,6 +314,7 @@
* [LongDivision](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LongDivision.java)
* [LucasSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LucasSeries.java)
* [MagicSquare](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MagicSquare.java)
+ * [MatrixRank](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MatrixRank.java)
* [MatrixUtil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MatrixUtil.java)
* [MaxValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MaxValue.java)
* [Means](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Means.java)
@@ -359,6 +367,7 @@
* misc
* [ColorContrastRatio](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java)
* [InverseOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java)
+ * [MapReduce](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MapReduce.java)
* [matrixTranspose](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/matrixTranspose.java)
* [MedianOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java)
* [MedianOfRunningArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java)
@@ -564,6 +573,7 @@
* [PowerSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PowerSumTest.java)
* [WordSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/WordSearchTest.java)
* bitmanipulation
+ * [BitSwapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java)
* [HighestSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java)
* [IndexOfRightMostSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java)
* [IsEvenTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java)
@@ -605,9 +615,12 @@
* [LFUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java)
* [LRUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java)
* [MRUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java)
+ * crdt
+ * [GCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java)
* disjointsetunion
* [DisjointSetUnionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java)
* graphs
+ * [BoruvkaAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java)
* [HamiltonianCycleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java)
* [KosarajuTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java)
* [TarjansAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithmTest.java)
@@ -666,6 +679,7 @@
* [OptimalJobSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java)
* [PartitionProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java)
* [SubsetCountTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java)
+ * [TribonacciTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java)
* [UniquePathsTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java)
* [WildcardMatchingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java)
* geometry
@@ -700,7 +714,9 @@
* [FastInverseSqrtTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java)
* [FFTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FFTTest.java)
* [FibonacciJavaStreamsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java)
+ * [FibonacciLoopTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java)
* [FibonacciNumberCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciNumberCheckTest.java)
+ * [FibonacciNumberGoldenRationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java)
* [FindMaxRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java)
* [FindMaxTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMaxTest.java)
* [FindMinRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java)
@@ -719,6 +735,7 @@
* [LiouvilleLambdaFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java)
* [LongDivisionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LongDivisionTest.java)
* [LucasSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LucasSeriesTest.java)
+ * [MatrixRankTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MatrixRankTest.java)
* [MaxValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MaxValueTest.java)
* [MeansTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MeansTest.java)
* [MedianTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MedianTest.java)
@@ -755,6 +772,7 @@
* [TwinPrimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/TwinPrimeTest.java)
* [VolumeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/VolumeTest.java)
* misc
+ * [MapReduceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MapReduceTest.java)
* [MedianOfMatrixtest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java)
* [MedianOfRunningArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java)
* [MirrorOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java)
@@ -763,6 +781,7 @@
* others
* [ArrayLeftRotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java)
* [BestFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/BestFitCPUTest.java)
+ * [BoyerMooreTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/BoyerMooreTest.java)
* cn
* [HammingDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/cn/HammingDistanceTest.java)
* [ConwayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ConwayTest.java)
@@ -798,6 +817,7 @@
* [HowManyTimesRotatedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java)
* [KMPSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/KMPSearchTest.java)
* [OrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java)
+ * [PerfectBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java)
* [QuickSelectTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/QuickSelectTest.java)
* [RabinKarpAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java)
* [RecursiveBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java)
diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java b/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java
new file mode 100644
index 000000000000..dcdb08ad133e
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java
@@ -0,0 +1,217 @@
+package com.thealgorithms.datastructures.graphs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Boruvka's algorithm to find Minimum Spanning Tree
+ * (https://en.wikipedia.org/wiki/Bor%C5%AFvka%27s_algorithm)
+ *
+ * @author itakurah (https://github.com/itakurah)
+ */
+
+final class BoruvkaAlgorithm {
+ private BoruvkaAlgorithm() {
+ }
+
+ /**
+ * Represents an edge in the graph
+ */
+ static class Edge {
+ final int src;
+ final int dest;
+ final int weight;
+
+ Edge(final int src, final int dest, final int weight) {
+ this.src = src;
+ this.dest = dest;
+ this.weight = weight;
+ }
+ }
+
+ /**
+ * Represents the graph
+ */
+ static class Graph {
+ final int vertex;
+ final List edges;
+
+ /**
+ * Constructor for the graph
+ *
+ * @param vertex number of vertices
+ * @param edges list of edges
+ */
+ Graph(final int vertex, final List edges) {
+ if (vertex < 0) {
+ throw new IllegalArgumentException("Number of vertices must be positive");
+ }
+ if (edges == null || edges.isEmpty()) {
+ throw new IllegalArgumentException("Edges list must not be null or empty");
+ }
+ for (final var edge : edges) {
+ checkEdgeVertices(edge.src, vertex);
+ checkEdgeVertices(edge.dest, vertex);
+ }
+
+ this.vertex = vertex;
+ this.edges = edges;
+ }
+ }
+
+ /**
+ * Represents a subset for Union-Find operations
+ */
+ private static class Component {
+ int parent;
+ int rank;
+
+ Component(final int parent, final int rank) {
+ this.parent = parent;
+ this.rank = rank;
+ }
+ }
+
+ /**
+ * Represents the state of Union-Find components and the result list
+ */
+ private static class BoruvkaState {
+ List result;
+ Component[] components;
+ final Graph graph;
+
+ BoruvkaState(final Graph graph) {
+ this.result = new ArrayList<>();
+ this.components = initializeComponents(graph);
+ this.graph = graph;
+ }
+
+ /**
+ * Adds the cheapest edges to the result list and performs Union operation on the subsets.
+ *
+ * @param cheapest Array containing the cheapest edge for each subset.
+ */
+ void merge(final Edge[] cheapest) {
+ for (int i = 0; i < graph.vertex; ++i) {
+ if (cheapest[i] != null) {
+ final var component1 = find(components, cheapest[i].src);
+ final var component2 = find(components, cheapest[i].dest);
+
+ if (component1 != component2) {
+ result.add(cheapest[i]);
+ union(components, component1, component2);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks if there are more edges to add to the result list
+ *
+ * @return true if there are more edges to add, false otherwise
+ */
+ boolean hasMoreEdgesToAdd() {
+ return result.size() < graph.vertex - 1;
+ }
+
+ /**
+ * Computes the cheapest edges for each subset in the Union-Find structure.
+ *
+ * @return an array containing the cheapest edge for each subset.
+ */
+ private Edge[] computeCheapestEdges() {
+ Edge[] cheapest = new Edge[graph.vertex];
+ for (final var edge : graph.edges) {
+ final var set1 = find(components, edge.src);
+ final var set2 = find(components, edge.dest);
+
+ if (set1 != set2) {
+ if (cheapest[set1] == null || edge.weight < cheapest[set1].weight) {
+ cheapest[set1] = edge;
+ }
+ if (cheapest[set2] == null || edge.weight < cheapest[set2].weight) {
+ cheapest[set2] = edge;
+ }
+ }
+ }
+ return cheapest;
+ }
+
+ /**
+ * Initializes subsets for Union-Find
+ *
+ * @param graph the graph
+ * @return the initialized subsets
+ */
+ private static Component[] initializeComponents(final Graph graph) {
+ Component[] components = new Component[graph.vertex];
+ for (int v = 0; v < graph.vertex; ++v) {
+ components[v] = new Component(v, 0);
+ }
+ return components;
+ }
+ }
+
+ /**
+ * Finds the parent of the subset using path compression
+ *
+ * @param components array of subsets
+ * @param i index of the subset
+ * @return the parent of the subset
+ */
+ static int find(final Component[] components, final int i) {
+ if (components[i].parent != i) {
+ components[i].parent = find(components, components[i].parent);
+ }
+ return components[i].parent;
+ }
+
+ /**
+ * Performs the Union operation for Union-Find
+ *
+ * @param components array of subsets
+ * @param x index of the first subset
+ * @param y index of the second subset
+ */
+ static void union(Component[] components, final int x, final int y) {
+ final int xroot = find(components, x);
+ final int yroot = find(components, y);
+
+ if (components[xroot].rank < components[yroot].rank) {
+ components[xroot].parent = yroot;
+ } else if (components[xroot].rank > components[yroot].rank) {
+ components[yroot].parent = xroot;
+ } else {
+ components[yroot].parent = xroot;
+ components[xroot].rank++;
+ }
+ }
+
+ /**
+ * Boruvka's algorithm to find the Minimum Spanning Tree
+ *
+ * @param graph the graph
+ * @return list of edges in the Minimum Spanning Tree
+ */
+ static List boruvkaMST(final Graph graph) {
+ var boruvkaState = new BoruvkaState(graph);
+
+ while (boruvkaState.hasMoreEdgesToAdd()) {
+ final var cheapest = boruvkaState.computeCheapestEdges();
+ boruvkaState.merge(cheapest);
+ }
+ return boruvkaState.result;
+ }
+
+ /**
+ * Checks if the edge vertices are in a valid range
+ *
+ * @param vertex the vertex to check
+ * @param upperBound the upper bound for the vertex range
+ */
+ private static void checkEdgeVertices(final int vertex, final int upperBound) {
+ if (vertex < 0 || vertex >= upperBound) {
+ throw new IllegalArgumentException("Edge vertex out of range");
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java b/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java
new file mode 100644
index 000000000000..b5f75f5e831e
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java
@@ -0,0 +1,191 @@
+package com.thealgorithms.datastructures.graphs;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.thealgorithms.datastructures.graphs.BoruvkaAlgorithm.Graph;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+public class BoruvkaAlgorithmTest {
+ @Test
+ public void testBoruvkaMSTV9E14() {
+ List edges = new ArrayList<>();
+
+ edges.add(new BoruvkaAlgorithm.Edge(0, 1, 10));
+ edges.add(new BoruvkaAlgorithm.Edge(0, 2, 12));
+ edges.add(new BoruvkaAlgorithm.Edge(1, 2, 9));
+ edges.add(new BoruvkaAlgorithm.Edge(1, 3, 8));
+ edges.add(new BoruvkaAlgorithm.Edge(2, 4, 3));
+ edges.add(new BoruvkaAlgorithm.Edge(2, 5, 1));
+ edges.add(new BoruvkaAlgorithm.Edge(4, 5, 3));
+ edges.add(new BoruvkaAlgorithm.Edge(4, 3, 7));
+ edges.add(new BoruvkaAlgorithm.Edge(3, 6, 8));
+ edges.add(new BoruvkaAlgorithm.Edge(3, 7, 5));
+ edges.add(new BoruvkaAlgorithm.Edge(5, 7, 6));
+ edges.add(new BoruvkaAlgorithm.Edge(6, 7, 9));
+ edges.add(new BoruvkaAlgorithm.Edge(6, 8, 2));
+ edges.add(new BoruvkaAlgorithm.Edge(7, 8, 11));
+
+ final var graph = new Graph(9, edges);
+ /**
+ * Adjacency matrix
+ * 0 1 2 3 4 5 6 7 8
+ * 0 0 10 12 0 0 0 0 0 0
+ * 1 10 0 9 8 0 0 0 0 0
+ * 2 12 9 0 0 3 1 0 0 0
+ * 3 0 8 0 0 7 0 8 5 0
+ * 4 0 0 3 7 0 3 0 0 0
+ * 5 0 0 1 0 3 0 0 6 0
+ * 6 0 0 0 8 0 0 0 9 2
+ * 7 0 0 0 5 0 6 9 0 11
+ * 8 0 0 0 0 0 0 2 11 0
+ */
+ final var result = BoruvkaAlgorithm.boruvkaMST(graph);
+ assertEquals(8, result.size());
+ assertEquals(43, computeTotalWeight(result));
+ }
+
+ @Test
+ void testBoruvkaMSTV2E1() {
+ List edges = new ArrayList<>();
+
+ edges.add(new BoruvkaAlgorithm.Edge(0, 1, 10));
+
+ final var graph = new Graph(2, edges);
+
+ /**
+ * Adjacency matrix
+ * 0 1
+ * 0 0 10
+ * 1 10 0
+ */
+ final var result = BoruvkaAlgorithm.boruvkaMST(graph);
+ assertEquals(1, result.size());
+ assertEquals(10, computeTotalWeight(result));
+ }
+
+ @Test
+ void testCompleteGraphK4() {
+ List edges = new ArrayList<>();
+ edges.add(new BoruvkaAlgorithm.Edge(0, 1, 7));
+ edges.add(new BoruvkaAlgorithm.Edge(0, 2, 2));
+ edges.add(new BoruvkaAlgorithm.Edge(0, 3, 5));
+ edges.add(new BoruvkaAlgorithm.Edge(1, 2, 3));
+ edges.add(new BoruvkaAlgorithm.Edge(1, 3, 4));
+ edges.add(new BoruvkaAlgorithm.Edge(2, 3, 1));
+
+ final var graph = new Graph(4, edges);
+
+ /**
+ * Adjacency matrix
+ * 0 1 2 3
+ * 0 0 7 2 5
+ * 1 7 0 3 4
+ * 2 2 3 0 1
+ * 3 5 4 1 0
+ */
+ final var result = BoruvkaAlgorithm.boruvkaMST(graph);
+ assertEquals(3, result.size());
+ assertEquals(6, computeTotalWeight(result));
+ }
+
+ @Test
+ void testNegativeVertices() {
+ Exception exception1 = assertThrows(IllegalArgumentException.class, () -> new Graph(-1, null));
+ String expectedMessage = "Number of vertices must be positive";
+ String actualMessage = exception1.getMessage();
+
+ assertTrue(actualMessage.contains(expectedMessage));
+ }
+
+ @Test
+ void testEdgesNull() {
+ Exception exception = assertThrows(IllegalArgumentException.class, () -> new Graph(0, null));
+ String expectedMessage = "Edges list must not be null or empty";
+ String actualMessage = exception.getMessage();
+
+ assertTrue(actualMessage.contains(expectedMessage));
+ }
+
+ @Test
+ void testEdgesEmpty() {
+ Exception exception = assertThrows(IllegalArgumentException.class, () -> new Graph(0, new ArrayList<>()));
+ String expectedMessage = "Edges list must not be null or empty";
+ String actualMessage = exception.getMessage();
+
+ assertTrue(actualMessage.contains(expectedMessage));
+ }
+
+ @Test
+ void testEdgesRange() {
+ // Valid input
+ List validEdges = new ArrayList<>();
+ validEdges.add(new BoruvkaAlgorithm.Edge(0, 1, 2));
+ validEdges.add(new BoruvkaAlgorithm.Edge(1, 2, 3));
+ final var validGraph = new BoruvkaAlgorithm.Graph(3, validEdges);
+ assertEquals(validEdges, validGraph.edges);
+
+ // Edge source out of range
+ Exception exception1 = assertThrows(IllegalArgumentException.class, () -> {
+ List invalidEdges = new ArrayList<>();
+ invalidEdges.add(new BoruvkaAlgorithm.Edge(-1, 1, 2));
+ final var invalidGraph = new BoruvkaAlgorithm.Graph(1, invalidEdges);
+ assertEquals(invalidEdges, invalidGraph.edges);
+ });
+ String expectedMessage1 = "Edge vertex out of range";
+ String actualMessage1 = exception1.getMessage();
+
+ assertTrue(actualMessage1.contains(expectedMessage1));
+
+ // Edge source out of range
+ Exception exception2 = assertThrows(IllegalArgumentException.class, () -> {
+ List invalidEdges = new ArrayList<>();
+ invalidEdges.add(new BoruvkaAlgorithm.Edge(1, 0, 2));
+ final var invalidGraph = new BoruvkaAlgorithm.Graph(1, invalidEdges);
+ assertEquals(invalidEdges, invalidGraph.edges);
+ });
+ String expectedMessage2 = "Edge vertex out of range";
+ String actualMessage2 = exception2.getMessage();
+
+ assertTrue(actualMessage2.contains(expectedMessage2));
+
+ // Edge destination out of range
+ Exception exception3 = assertThrows(IllegalArgumentException.class, () -> {
+ List invalidEdges = new ArrayList<>();
+ invalidEdges.add(new BoruvkaAlgorithm.Edge(0, -1, 2));
+ final var invalidGraph = new BoruvkaAlgorithm.Graph(1, invalidEdges);
+ assertEquals(invalidEdges, invalidGraph.edges);
+ });
+ String expectedMessage3 = "Edge vertex out of range";
+ String actualMessage3 = exception3.getMessage();
+
+ assertTrue(actualMessage3.contains(expectedMessage3));
+
+ // Edge destination out of range
+ Exception exception4 = assertThrows(IllegalArgumentException.class, () -> {
+ List invalidEdges = new ArrayList<>();
+ invalidEdges.add(new BoruvkaAlgorithm.Edge(0, 1, 2));
+ final var invalidGraph = new BoruvkaAlgorithm.Graph(1, invalidEdges);
+ assertEquals(invalidEdges, invalidGraph.edges);
+ });
+ String expectedMessage4 = "Edge vertex out of range";
+ String actualMessage4 = exception4.getMessage();
+
+ assertTrue(actualMessage4.contains(expectedMessage4));
+ }
+
+ /**
+ * Computes the total weight of the Minimum Spanning Tree
+ *
+ * @param result list of edges in the Minimum Spanning Tree
+ * @return the total weight of the Minimum Spanning Tree
+ */
+ int computeTotalWeight(final List result) {
+ int totalWeight = 0;
+ for (final var edge : result) {
+ totalWeight += edge.weight;
+ }
+ return totalWeight;
+ }
+}
From 3001620c1eef3246f666c459f096ba390afce06b Mon Sep 17 00:00:00 2001
From: Niklas Hoefflin <122729995+itakurah@users.noreply.github.com>
Date: Mon, 4 Dec 2023 17:22:02 +0100
Subject: [PATCH 0073/1151] Add PN-Counter (#4974)
---
DIRECTORY.md | 2 +
.../datastructures/crdt/PNCounter.java | 100 ++++++++++++++++++
.../datastructures/crdt/PNCounterTest.java | 54 ++++++++++
3 files changed, 156 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java
create mode 100644 src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 89f08c27248b..0548d3455581 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -84,6 +84,7 @@
* [MRUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java)
* crdt
* [GCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java)
+ * [PNCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java)
* disjointsetunion
* [DisjointSetUnion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java)
* [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java)
@@ -617,6 +618,7 @@
* [MRUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java)
* crdt
* [GCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java)
+ * [PNCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java)
* disjointsetunion
* [DisjointSetUnionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java)
* graphs
diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java b/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java
new file mode 100644
index 000000000000..828e0b0804b3
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java
@@ -0,0 +1,100 @@
+package com.thealgorithms.datastructures.crdt;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * PN-Counter (Positive-Negative Counter) is a state-based CRDT (Conflict-free Replicated Data Type)
+ * designed for tracking counts with both increments and decrements in a distributed and concurrent environment.
+ * It combines two G-Counters, one for increments (P) and one for decrements (N).
+ * The total count is obtained by subtracting the value of the decrement counter from the increment counter.
+ * This implementation supports incrementing, decrementing, querying the total count,
+ * comparing with other PN-Counters, and merging with another PN-Counter
+ * to compute the element-wise maximum for both increment and decrement counters.
+ * (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type)
+ *
+ * @author itakurah (Niklas Hoefflin) (https://github.com/itakurah)
+ */
+
+class PNCounter {
+ private final Map P;
+ private final Map N;
+ private final int myId;
+ private final int n;
+
+ /**
+ * Constructs a PN-Counter for a cluster of n nodes.
+ *
+ * @param myId The identifier of the current node.
+ * @param n The number of nodes in the cluster.
+ */
+ public PNCounter(int myId, int n) {
+ this.myId = myId;
+ this.n = n;
+ this.P = new HashMap<>();
+ this.N = new HashMap<>();
+
+ for (int i = 0; i < n; i++) {
+ P.put(i, 0);
+ N.put(i, 0);
+ }
+ }
+
+ /**
+ * Increments the increment counter for the current node.
+ */
+ public void increment() {
+ P.put(myId, P.get(myId) + 1);
+ }
+
+ /**
+ * Increments the decrement counter for the current node.
+ */
+ public void decrement() {
+ N.put(myId, N.get(myId) + 1);
+ }
+
+ /**
+ * Gets the total value of the counter by subtracting the decrement counter from the increment counter.
+ *
+ * @return The total value of the counter.
+ */
+ public int value() {
+ int sumP = P.values().stream().mapToInt(Integer::intValue).sum();
+ int sumN = N.values().stream().mapToInt(Integer::intValue).sum();
+ return sumP - sumN;
+ }
+
+ /**
+ * Compares the state of this PN-Counter with another PN-Counter.
+ *
+ * @param other The other PN-Counter to compare with.
+ * @return True if the state of this PN-Counter is less than or equal to the state of the other PN-Counter.
+ */
+ public boolean compare(PNCounter other) {
+ if (this.n != other.n) {
+ throw new IllegalArgumentException("Cannot compare PN-Counters with different number of nodes");
+ }
+ for (int i = 0; i < n; i++) {
+ if (this.P.get(i) > other.P.get(i) && this.N.get(i) > other.N.get(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Merges the state of this PN-Counter with another PN-Counter.
+ *
+ * @param other The other PN-Counter to merge with.
+ */
+ public void merge(PNCounter other) {
+ if (this.n != other.n) {
+ throw new IllegalArgumentException("Cannot merge PN-Counters with different number of nodes");
+ }
+ for (int i = 0; i < n; i++) {
+ this.P.put(i, Math.max(this.P.get(i), other.P.get(i)));
+ this.N.put(i, Math.max(this.N.get(i), other.N.get(i)));
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java
new file mode 100644
index 000000000000..46c22a6edcb7
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java
@@ -0,0 +1,54 @@
+package com.thealgorithms.datastructures.crdt;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class PNCounterTest {
+
+ @Test
+ public void testIncrement() {
+ PNCounter counter = new PNCounter(0, 3);
+ counter.increment();
+ assertEquals(1, counter.value());
+ }
+
+ @Test
+ public void testDecrement() {
+ PNCounter counter = new PNCounter(0, 3);
+ counter.decrement();
+ assertEquals(-1, counter.value());
+ }
+
+ @Test
+ public void testIncrementAndDecrement() {
+ PNCounter counter = new PNCounter(0, 3);
+ counter.increment();
+ counter.increment();
+ counter.decrement();
+ assertEquals(1, counter.value());
+ }
+
+ @Test
+ public void testCompare() {
+ PNCounter counter1 = new PNCounter(0, 3);
+ counter1.increment();
+ PNCounter counter2 = new PNCounter(1, 3);
+ assertTrue(counter1.compare(counter2));
+ counter2.increment();
+ assertTrue(counter2.compare(counter1));
+ counter1.decrement();
+ assertFalse(counter1.compare(counter2));
+ }
+
+ @Test
+ public void testMerge() {
+ PNCounter counter1 = new PNCounter(0, 3);
+ counter1.increment();
+ counter1.increment();
+ PNCounter counter2 = new PNCounter(1, 3);
+ counter2.increment();
+ counter1.merge(counter2);
+ assertEquals(3, counter1.value());
+ }
+}
From e59a3b1ebba0b484fad64adb06aedc06eb366825 Mon Sep 17 00:00:00 2001
From: Niklas Hoefflin <122729995+itakurah@users.noreply.github.com>
Date: Tue, 5 Dec 2023 19:39:18 +0100
Subject: [PATCH 0074/1151] Add G-Set (Grow-only Set) (#4975)
---
DIRECTORY.md | 2 +
.../datastructures/crdt/GSet.java | 65 +++++++++++++++++
.../datastructures/crdt/GSetTest.java | 71 +++++++++++++++++++
3 files changed, 138 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/datastructures/crdt/GSet.java
create mode 100644 src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 0548d3455581..4a94809560a1 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -84,6 +84,7 @@
* [MRUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java)
* crdt
* [GCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java)
+ * [GSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java)
* [PNCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java)
* disjointsetunion
* [DisjointSetUnion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java)
@@ -618,6 +619,7 @@
* [MRUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java)
* crdt
* [GCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java)
+ * [GSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java)
* [PNCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java)
* disjointsetunion
* [DisjointSetUnionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java)
diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java
new file mode 100644
index 000000000000..37873adc2573
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java
@@ -0,0 +1,65 @@
+package com.thealgorithms.datastructures.crdt;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * GSet (Grow-only Set) is a state-based CRDT (Conflict-free Replicated Data Type)
+ * that allows only the addition of elements and ensures that once an element is added,
+ * it cannot be removed. The merge operation of two G-Sets is their union.
+ * This implementation supports adding elements, looking up elements, comparing with other G-Sets,
+ * and merging with another G-Set to create a new G-Set containing all unique elements from both sets.
+ * (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type)
+ *
+ * @author itakurah (Niklas Hoefflin) (https://github.com/itakurah)
+ */
+
+public class GSet {
+ private final Set elements;
+
+ /**
+ * Constructs an empty G-Set.
+ */
+ public GSet() {
+ this.elements = new HashSet<>();
+ }
+
+ /**
+ * Adds an element to the G-Set.
+ *
+ * @param e the element to be added
+ */
+ public void addElement(T e) {
+ elements.add(e);
+ }
+
+ /**
+ * Checks if the given element is present in the G-Set.
+ *
+ * @param e the element to be checked
+ * @return true if the element is present, false otherwise
+ */
+ public boolean lookup(T e) {
+ return elements.contains(e);
+ }
+
+ /**
+ * Compares the G-Set with another G-Set to check if it is a subset.
+ *
+ * @param other the other G-Set to compare with
+ * @return true if the current G-Set is a subset of the other, false otherwise
+ */
+ public boolean compare(GSet other) {
+ return elements.containsAll(other.elements);
+ }
+
+ /**
+ * Merges the current G-Set with another G-Set, creating a new G-Set
+ * containing all unique elements from both sets.
+ *
+ * @param other the G-Set to merge with
+ */
+ public void merge(GSet other) {
+ elements.addAll(other.elements);
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java
new file mode 100644
index 000000000000..99588259006f
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java
@@ -0,0 +1,71 @@
+package com.thealgorithms.datastructures.crdt;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+class GSetTest {
+
+ @Test
+ void testAddElement() {
+ GSet gSet = new GSet<>();
+ gSet.addElement("apple");
+ gSet.addElement("orange");
+
+ assertTrue(gSet.lookup("apple"));
+ assertTrue(gSet.lookup("orange"));
+ assertFalse(gSet.lookup("banana"));
+ }
+
+ @Test
+ void testLookup() {
+ GSet gSet = new GSet<>();
+ gSet.addElement(1);
+ gSet.addElement(2);
+
+ assertTrue(gSet.lookup(1));
+ assertTrue(gSet.lookup(2));
+ assertFalse(gSet.lookup(3));
+ }
+
+ @Test
+ void testCompare() {
+ GSet gSet1 = new GSet<>();
+ GSet gSet2 = new GSet<>();
+
+ gSet1.addElement("apple");
+ gSet1.addElement("orange");
+
+ gSet2.addElement("orange");
+ gSet2.addElement("banana");
+
+ assertFalse(gSet1.compare(gSet2));
+
+ GSet gSet3 = new GSet<>();
+ gSet3.addElement("apple");
+ gSet3.addElement("orange");
+
+ assertTrue(gSet1.compare(gSet3));
+ }
+
+ @Test
+ void testMerge() {
+ GSet gSet1 = new GSet<>();
+ GSet gSet2 = new GSet<>();
+
+ gSet1.addElement("apple");
+ gSet1.addElement("orange");
+
+ gSet2.addElement("orange");
+ gSet2.addElement("banana");
+
+ GSet mergedSet = new GSet<>();
+ mergedSet.merge(gSet1);
+ mergedSet.merge(gSet2);
+
+ assertTrue(mergedSet.lookup("apple"));
+ assertTrue(mergedSet.lookup("orange"));
+ assertTrue(mergedSet.lookup("banana"));
+ assertFalse(mergedSet.lookup("grape"));
+ }
+}
From 36580bac1e1901486950a2df27e534665f47e6b7 Mon Sep 17 00:00:00 2001
From: Nassor Shabataka <86209375+ImmaculateShaba@users.noreply.github.com>
Date: Wed, 6 Dec 2023 02:37:58 -0500
Subject: [PATCH 0075/1151] Fix typo in NextGraterElement (#4976)
---
...erElement.java => NextGreaterElement.java} | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
rename src/main/java/com/thealgorithms/stacks/{NextGraterElement.java => NextGreaterElement.java} (69%)
diff --git a/src/main/java/com/thealgorithms/stacks/NextGraterElement.java b/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java
similarity index 69%
rename from src/main/java/com/thealgorithms/stacks/NextGraterElement.java
rename to src/main/java/com/thealgorithms/stacks/NextGreaterElement.java
index 0cf56349c662..d681e41fbfc3 100644
--- a/src/main/java/com/thealgorithms/stacks/NextGraterElement.java
+++ b/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java
@@ -4,26 +4,26 @@
import java.util.Stack;
/*
- Given an array "input" you need to print the first grater element for each element.
- For a given element x of an array, the Next Grater element of that element is the
- first grater element to the right side of it. If no such element is present print -1.
+ Given an array "input" you need to print the first greater element for each element.
+ For a given element x of an array, the Next greater element of that element is the
+ first greater element to the right side of it. If no such element is present print -1.
Example
input = { 2, 7, 3, 5, 4, 6, 8 };
At i = 0
- Next Grater element between (1 to n) is 7
+ Next greater element between (1 to n) is 7
At i = 1
- Next Grater element between (2 to n) is 8
+ Next greater element between (2 to n) is 8
At i = 2
- Next Grater element between (3 to n) is 5
+ Next greater element between (3 to n) is 5
At i = 3
- Next Grater element between (4 to n) is 6
+ Next greater element between (4 to n) is 6
At i = 4
- Next Grater element between (5 to n) is 6
+ Next greater element between (5 to n) is 6
At i = 5
- Next Grater element between (6 to n) is 8
+ Next greater element between (6 to n) is 8
At i = 6
- Next Grater element between (6 to n) is -1
+ Next greater element between (6 to n) is -1
result : [7, 8, 5, 6, 6, 8, -1]
@@ -37,11 +37,11 @@ Next Grater element between (6 to n) is -1
popped elements.
d. Finally, push the next in the stack.
- 3. If elements are left in stack after completing while loop then their Next Grater element is
+ 3. If elements are left in stack after completing while loop then their Next greater element is
-1.
*/
-public class NextGraterElement {
+public class NextGreaterElement {
public static int[] findNextGreaterElements(int[] array) {
if (array == null) {
From 249ee1dc994735a6cf02a6048ab8bedd2e91ce4a Mon Sep 17 00:00:00 2001
From: Niklas Hoefflin <122729995+itakurah@users.noreply.github.com>
Date: Thu, 7 Dec 2023 16:23:22 +0100
Subject: [PATCH 0076/1151] Add 2P-Set (Two-Phase Set) for both addition and
removal operations in distributed systems (#4977)
---
DIRECTORY.md | 4 +-
.../datastructures/crdt/TwoPSet.java | 84 +++++++++++++++++++
.../datastructures/crdt/TwoPSetTest.java | 68 +++++++++++++++
3 files changed, 155 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java
create mode 100644 src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 4a94809560a1..703642a0d28e 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -86,6 +86,7 @@
* [GCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java)
* [GSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java)
* [PNCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java)
+ * [TwoPSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java)
* disjointsetunion
* [DisjointSetUnion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java)
* [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java)
@@ -528,7 +529,7 @@
* [InfixToPostfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java)
* [LargestRectangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/LargestRectangle.java)
* [MaximumMinimumWindow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java)
- * [NextGraterElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextGraterElement.java)
+ * [NextGreaterElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java)
* [NextSmallerElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java)
* [PostfixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java)
* [StackPostfixNotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java)
@@ -621,6 +622,7 @@
* [GCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java)
* [GSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java)
* [PNCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java)
+ * [TwoPSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java)
* disjointsetunion
* [DisjointSetUnionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java)
* graphs
diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java
new file mode 100644
index 000000000000..f5e155c28d8d
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java
@@ -0,0 +1,84 @@
+package com.thealgorithms.datastructures.crdt;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * TwoPhaseSet (2P-Set) is a state-based CRDT (Conflict-free Replicated Data Type) designed for managing sets
+ * with support for both addition and removal operations in a distributed and concurrent environment.
+ * It combines two G-Sets (grow-only sets) - one set for additions and another set (tombstone set) for removals.
+ * Once an element is removed and placed in the tombstone set, it cannot be re-added, adhering to "remove-wins" semantics.
+ * This implementation supports querying the presence of elements, adding elements, removing elements,
+ * comparing with other 2P-Sets, and merging two 2P-Sets while preserving the remove-wins semantics.
+ * (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type)
+ *
+ * @author itakurah (Niklas Hoefflin) (https://github.com/itakurah)
+ */
+
+public class TwoPSet {
+ private Set setA;
+ private Set setR;
+
+ /**
+ * Constructs an empty Two-Phase Set.
+ */
+ public TwoPSet() {
+ this.setA = new HashSet<>();
+ this.setR = new HashSet<>();
+ }
+
+ /**
+ * Checks if an element is in the set and has not been removed.
+ *
+ * @param element The element to be checked.
+ * @return True if the element is in the set and has not been removed, otherwise false.
+ */
+ public boolean lookup(String element) {
+ return setA.contains(element) && !setR.contains(element);
+ }
+
+ /**
+ * Adds an element to the set.
+ *
+ * @param element The element to be added.
+ */
+ public void add(String element) {
+ setA.add(element);
+ }
+
+ /**
+ * Removes an element from the set. The element will be placed in the tombstone set.
+ *
+ * @param element The element to be removed.
+ */
+ public void remove(String element) {
+ if (lookup(element)) {
+ setR.add(element);
+ }
+ }
+
+ /**
+ * Compares the current 2P-Set with another 2P-Set.
+ *
+ * @param otherSet The other 2P-Set to compare with.
+ * @return True if both SetA and SetR are subset, otherwise false.
+ */
+ public boolean compare(TwoPSet otherSet) {
+ return otherSet.setA.containsAll(setA) && otherSet.setR.containsAll(setR);
+ }
+
+ /**
+ * Merges the current 2P-Set with another 2P-Set.
+ *
+ * @param otherSet The other 2P-Set to merge with.
+ * @return A new 2P-Set containing the merged elements.
+ */
+ public TwoPSet merge(TwoPSet otherSet) {
+ TwoPSet mergedSet = new TwoPSet();
+ mergedSet.setA.addAll(this.setA);
+ mergedSet.setA.addAll(otherSet.setA);
+ mergedSet.setR.addAll(this.setR);
+ mergedSet.setR.addAll(otherSet.setR);
+ return mergedSet;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java
new file mode 100644
index 000000000000..18ab5c169e5c
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java
@@ -0,0 +1,68 @@
+package com.thealgorithms.datastructures.crdt;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class TwoPSetTest {
+
+ private TwoPSet set;
+
+ @BeforeEach
+ void setUp() {
+ set = new TwoPSet();
+ }
+
+ @Test
+ void testLookup() {
+ set.add("A");
+ assertTrue(set.lookup("A"));
+ assertFalse(set.lookup("B"));
+ set.remove("A");
+ assertFalse(set.lookup("A"));
+ }
+
+ @Test
+ void testAdd() {
+ set.add("A");
+ assertTrue(set.lookup("A"));
+ }
+
+ @Test
+ void testRemove() {
+ set.add("A");
+ set.remove("A");
+ assertFalse(set.lookup("A"));
+ }
+
+ @Test
+ void testCompare() {
+ TwoPSet set1 = new TwoPSet();
+ set1.add("A");
+ set1.add("B");
+ TwoPSet set2 = new TwoPSet();
+ set2.add("A");
+ assertFalse(set1.compare(set2));
+ set2.add("B");
+ assertTrue(set1.compare(set2));
+ set1.remove("A");
+ assertFalse(set1.compare(set2));
+ set2.remove("A");
+ assertTrue(set1.compare(set2));
+ }
+
+ @Test
+ void testMerge() {
+ TwoPSet set1 = new TwoPSet();
+ set1.add("A");
+ set1.add("B");
+ TwoPSet set2 = new TwoPSet();
+ set2.add("B");
+ set2.add("C");
+ TwoPSet mergedSet = set1.merge(set2);
+ assertTrue(mergedSet.lookup("A"));
+ assertTrue(mergedSet.lookup("B"));
+ assertTrue(mergedSet.lookup("C"));
+ }
+}
From 92131de3774d6dc7be7662bd0a8a9c02704255d5 Mon Sep 17 00:00:00 2001
From: Niklas Hoefflin <122729995+itakurah@users.noreply.github.com>
Date: Thu, 7 Dec 2023 17:06:56 +0100
Subject: [PATCH 0077/1151] =?UTF-8?q?Fix=20compare()=20for=20subset=20chec?=
=?UTF-8?q?k=20(S.A=20=E2=8A=86=20T.A)=20(#4978)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../thealgorithms/datastructures/crdt/GSet.java | 2 +-
.../datastructures/crdt/GSetTest.java | 14 ++++----------
2 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java
index 37873adc2573..2b8959ed0136 100644
--- a/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java
+++ b/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java
@@ -50,7 +50,7 @@ public boolean lookup(T e) {
* @return true if the current G-Set is a subset of the other, false otherwise
*/
public boolean compare(GSet other) {
- return elements.containsAll(other.elements);
+ return other.elements.containsAll(elements);
}
/**
diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java
index 99588259006f..74250ede1f23 100644
--- a/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java
+++ b/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java
@@ -32,20 +32,14 @@ void testLookup() {
void testCompare() {
GSet gSet1 = new GSet<>();
GSet gSet2 = new GSet<>();
-
gSet1.addElement("apple");
gSet1.addElement("orange");
-
gSet2.addElement("orange");
- gSet2.addElement("banana");
-
assertFalse(gSet1.compare(gSet2));
-
- GSet gSet3 = new GSet<>();
- gSet3.addElement("apple");
- gSet3.addElement("orange");
-
- assertTrue(gSet1.compare(gSet3));
+ gSet2.addElement("apple");
+ assertTrue(gSet1.compare(gSet2));
+ gSet2.addElement("banana");
+ assertTrue(gSet1.compare(gSet2));
}
@Test
From b8b1dea38de84d7647921cd1859b7d58303e9b86 Mon Sep 17 00:00:00 2001
From: Niklas Hoefflin <122729995+itakurah@users.noreply.github.com>
Date: Fri, 8 Dec 2023 19:57:07 +0100
Subject: [PATCH 0078/1151] Add LWW Element Set (Last Write Wins Element Set)
(#4979)
---
DIRECTORY.md | 2 +
.../datastructures/crdt/LWWElementSet.java | 138 ++++++++++++++++++
.../crdt/LWWElementSetTest.java | 107 ++++++++++++++
3 files changed, 247 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java
create mode 100644 src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 703642a0d28e..f033416dc38a 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -85,6 +85,7 @@
* crdt
* [GCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java)
* [GSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java)
+ * [LWWElementSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java)
* [PNCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java)
* [TwoPSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java)
* disjointsetunion
@@ -621,6 +622,7 @@
* crdt
* [GCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java)
* [GSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java)
+ * [LWWElementSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java)
* [PNCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java)
* [TwoPSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java)
* disjointsetunion
diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java
new file mode 100644
index 000000000000..722c916ab0ce
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java
@@ -0,0 +1,138 @@
+package com.thealgorithms.datastructures.crdt;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Last-Write-Wins Element Set (LWWElementSet) is a state-based CRDT (Conflict-free Replicated Data Type)
+ * designed for managing sets in a distributed and concurrent environment. It supports the addition and removal
+ * of elements, using timestamps to determine the order of operations. The set is split into two subsets:
+ * the add set for elements to be added and the remove set for elements to be removed.
+ *
+ * @author itakurah (Niklas Hoefflin) (https://github.com/itakurah)
+ * @see Conflict-free_replicated_data_type
+ * @see itakurah (Niklas Hoefflin)
+ */
+
+class Element {
+ String key;
+ int timestamp;
+ Bias bias;
+
+ /**
+ * Constructs a new Element with the specified key, timestamp and bias.
+ *
+ * @param key The key of the element.
+ * @param timestamp The timestamp associated with the element.
+ * @param bias The bias of the element (ADDS or REMOVALS).
+ */
+ public Element(String key, int timestamp, Bias bias) {
+ this.key = key;
+ this.timestamp = timestamp;
+ this.bias = bias;
+ }
+}
+
+enum Bias {
+ /**
+ * ADDS bias for the add set.
+ * REMOVALS bias for the remove set.
+ */
+ ADDS,
+ REMOVALS
+}
+
+class LWWElementSet {
+ private final Map addSet;
+ private final Map removeSet;
+
+ /**
+ * Constructs an empty LWWElementSet.
+ */
+ public LWWElementSet() {
+ this.addSet = new HashMap<>();
+ this.removeSet = new HashMap<>();
+ }
+
+ /**
+ * Adds an element to the addSet.
+ *
+ * @param e The element to be added.
+ */
+ public void add(Element e) {
+ addSet.put(e.key, e);
+ }
+
+ /**
+ * Removes an element from the removeSet.
+ *
+ * @param e The element to be removed.
+ */
+ public void remove(Element e) {
+ if (lookup(e)) {
+ removeSet.put(e.key, e);
+ }
+ }
+
+ /**
+ * Checks if an element is in the LWWElementSet by comparing timestamps in the addSet and removeSet.
+ *
+ * @param e The element to be checked.
+ * @return True if the element is present, false otherwise.
+ */
+ public boolean lookup(Element e) {
+ Element inAddSet = addSet.get(e.key);
+ Element inRemoveSet = removeSet.get(e.key);
+
+ return (inAddSet != null && (inRemoveSet == null || inAddSet.timestamp > inRemoveSet.timestamp));
+ }
+
+ /**
+ * Compares the LWWElementSet with another LWWElementSet to check if addSet and removeSet are a subset.
+ *
+ * @param other The LWWElementSet to compare.
+ * @return True if the set is subset, false otherwise.
+ */
+ public boolean compare(LWWElementSet other) {
+ return other.addSet.keySet().containsAll(addSet.keySet()) && other.removeSet.keySet().containsAll(removeSet.keySet());
+ }
+
+ /**
+ * Merges another LWWElementSet into this set by resolving conflicts based on timestamps.
+ *
+ * @param other The LWWElementSet to merge.
+ */
+ public void merge(LWWElementSet other) {
+ for (Element e : other.addSet.values()) {
+ if (!addSet.containsKey(e.key) || compareTimestamps(addSet.get(e.key), e)) {
+ addSet.put(e.key, e);
+ }
+ }
+
+ for (Element e : other.removeSet.values()) {
+ if (!removeSet.containsKey(e.key) || compareTimestamps(removeSet.get(e.key), e)) {
+ removeSet.put(e.key, e);
+ }
+ }
+ }
+
+ /**
+ * Compares timestamps of two elements based on their bias (ADDS or REMOVALS).
+ *
+ * @param e The first element.
+ * @param other The second element.
+ * @return True if the first element's timestamp is greater or the bias is ADDS and timestamps are equal.
+ */
+ public boolean compareTimestamps(Element e, Element other) {
+ if (!e.bias.equals(other.bias)) {
+ throw new IllegalArgumentException("Invalid bias value");
+ }
+ Bias bias = e.bias;
+ int timestampComparison = Integer.compare(e.timestamp, other.timestamp);
+
+ if (timestampComparison == 0) {
+ return !bias.equals(Bias.ADDS);
+ }
+ return timestampComparison < 0;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java
new file mode 100644
index 000000000000..6fb227bd80c5
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java
@@ -0,0 +1,107 @@
+package com.thealgorithms.datastructures.crdt;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class LWWElementSetTest {
+
+ private LWWElementSet set;
+ private final Bias bias = Bias.ADDS;
+
+ @BeforeEach
+ void setUp() {
+ set = new LWWElementSet();
+ }
+
+ @Test
+ void testAdd() {
+ Element element = new Element("key1", 1, bias);
+ set.add(element);
+
+ assertTrue(set.lookup(element));
+ }
+
+ @Test
+ void testRemove() {
+ Element element = new Element("key1", 1, bias);
+ set.add(element);
+ set.remove(element);
+
+ assertFalse(set.lookup(element));
+ }
+
+ @Test
+ void testRemoveNonexistentElement() {
+ Element element = new Element("key1", 1, bias);
+ set.remove(element);
+
+ assertFalse(set.lookup(element));
+ }
+
+ @Test
+ void testLookupNonexistentElement() {
+ Element element = new Element("key1", 1, bias);
+
+ assertFalse(set.lookup(element));
+ }
+
+ @Test
+ void testCompareEqualSets() {
+ LWWElementSet otherSet = new LWWElementSet();
+
+ Element element = new Element("key1", 1, bias);
+ set.add(element);
+ otherSet.add(element);
+
+ assertTrue(set.compare(otherSet));
+
+ otherSet.add(new Element("key2", 2, bias));
+ assertTrue(set.compare(otherSet));
+ }
+
+ @Test
+ void testCompareDifferentSets() {
+ LWWElementSet otherSet = new LWWElementSet();
+
+ Element element1 = new Element("key1", 1, bias);
+ Element element2 = new Element("key2", 2, bias);
+
+ set.add(element1);
+ otherSet.add(element2);
+
+ assertFalse(set.compare(otherSet));
+ }
+
+ @Test
+ void testMerge() {
+ LWWElementSet otherSet = new LWWElementSet();
+
+ Element element1 = new Element("key1", 1, bias);
+ Element element2 = new Element("key2", 2, bias);
+
+ set.add(element1);
+ otherSet.add(element2);
+
+ set.merge(otherSet);
+
+ assertTrue(set.lookup(element1));
+ assertTrue(set.lookup(element2));
+ }
+
+ @Test
+ void testCompareTimestampsEqualTimestamps() {
+ LWWElementSet lwwElementSet = new LWWElementSet();
+
+ Element e1 = new Element("key1", 10, Bias.REMOVALS);
+ Element e2 = new Element("key1", 10, Bias.REMOVALS);
+
+ assertTrue(lwwElementSet.compareTimestamps(e1, e2));
+
+ e1 = new Element("key1", 10, Bias.ADDS);
+ e2 = new Element("key1", 10, Bias.ADDS);
+
+ assertFalse(lwwElementSet.compareTimestamps(e1, e2));
+ }
+}
From 4aa8e6a0eb65e8edb9b716851ee4dd8881c434af Mon Sep 17 00:00:00 2001
From: Niklas Hoefflin <122729995+itakurah@users.noreply.github.com>
Date: Mon, 11 Dec 2023 19:58:56 +0100
Subject: [PATCH 0079/1151] Updated TwoPSet to use Generics instead of Strings
(#4981)
---
.../datastructures/crdt/TwoPSet.java | 18 +++++++++---------
.../datastructures/crdt/TwoPSetTest.java | 14 +++++++-------
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java
index f5e155c28d8d..c0ce17b2802b 100644
--- a/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java
+++ b/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java
@@ -15,9 +15,9 @@
* @author itakurah (Niklas Hoefflin) (https://github.com/itakurah)
*/
-public class TwoPSet {
- private Set setA;
- private Set setR;
+public class TwoPSet {
+ private final Set setA;
+ private final Set setR;
/**
* Constructs an empty Two-Phase Set.
@@ -33,7 +33,7 @@ public TwoPSet() {
* @param element The element to be checked.
* @return True if the element is in the set and has not been removed, otherwise false.
*/
- public boolean lookup(String element) {
+ public boolean lookup(T element) {
return setA.contains(element) && !setR.contains(element);
}
@@ -42,7 +42,7 @@ public boolean lookup(String element) {
*
* @param element The element to be added.
*/
- public void add(String element) {
+ public void add(T element) {
setA.add(element);
}
@@ -51,7 +51,7 @@ public void add(String element) {
*
* @param element The element to be removed.
*/
- public void remove(String element) {
+ public void remove(T element) {
if (lookup(element)) {
setR.add(element);
}
@@ -63,7 +63,7 @@ public void remove(String element) {
* @param otherSet The other 2P-Set to compare with.
* @return True if both SetA and SetR are subset, otherwise false.
*/
- public boolean compare(TwoPSet otherSet) {
+ public boolean compare(TwoPSet otherSet) {
return otherSet.setA.containsAll(setA) && otherSet.setR.containsAll(setR);
}
@@ -73,8 +73,8 @@ public boolean compare(TwoPSet otherSet) {
* @param otherSet The other 2P-Set to merge with.
* @return A new 2P-Set containing the merged elements.
*/
- public TwoPSet merge(TwoPSet otherSet) {
- TwoPSet mergedSet = new TwoPSet();
+ public TwoPSet merge(TwoPSet otherSet) {
+ TwoPSet mergedSet = new TwoPSet<>();
mergedSet.setA.addAll(this.setA);
mergedSet.setA.addAll(otherSet.setA);
mergedSet.setR.addAll(this.setR);
diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java
index 18ab5c169e5c..d81362e854d0 100644
--- a/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java
+++ b/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java
@@ -7,11 +7,11 @@
class TwoPSetTest {
- private TwoPSet set;
+ private TwoPSet set;
@BeforeEach
void setUp() {
- set = new TwoPSet();
+ set = new TwoPSet<>();
}
@Test
@@ -38,10 +38,10 @@ void testRemove() {
@Test
void testCompare() {
- TwoPSet set1 = new TwoPSet();
+ TwoPSet set1 = new TwoPSet<>();
set1.add("A");
set1.add("B");
- TwoPSet set2 = new TwoPSet();
+ TwoPSet set2 = new TwoPSet<>();
set2.add("A");
assertFalse(set1.compare(set2));
set2.add("B");
@@ -54,13 +54,13 @@ void testCompare() {
@Test
void testMerge() {
- TwoPSet set1 = new TwoPSet();
+ TwoPSet set1 = new TwoPSet<>();
set1.add("A");
set1.add("B");
- TwoPSet set2 = new TwoPSet();
+ TwoPSet set2 = new TwoPSet<>();
set2.add("B");
set2.add("C");
- TwoPSet mergedSet = set1.merge(set2);
+ TwoPSet mergedSet = set1.merge(set2);
assertTrue(mergedSet.lookup("A"));
assertTrue(mergedSet.lookup("B"));
assertTrue(mergedSet.lookup("C"));
From e26fd9da71130837d327d747f6bc87688322eee5 Mon Sep 17 00:00:00 2001
From: Niklas Hoefflin <122729995+itakurah@users.noreply.github.com>
Date: Mon, 11 Dec 2023 22:05:43 +0100
Subject: [PATCH 0080/1151] Add OR-Set (Observed-Remove Set) (#4980)
---
DIRECTORY.md | 2 +
.../datastructures/crdt/ORSet.java | 191 ++++++++++++++++++
.../datastructures/crdt/ORSetTest.java | 86 ++++++++
3 files changed, 279 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java
create mode 100644 src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index f033416dc38a..b769250e4749 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -86,6 +86,7 @@
* [GCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java)
* [GSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java)
* [LWWElementSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java)
+ * [ORSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java)
* [PNCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java)
* [TwoPSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java)
* disjointsetunion
@@ -623,6 +624,7 @@
* [GCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java)
* [GSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java)
* [LWWElementSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java)
+ * [ORSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java)
* [PNCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java)
* [TwoPSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java)
* disjointsetunion
diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java
new file mode 100644
index 000000000000..a4cc2ffdd4a6
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java
@@ -0,0 +1,191 @@
+package com.thealgorithms.datastructures.crdt;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * ORSet (Observed-Removed Set) is a state-based CRDT (Conflict-free Replicated Data Type)
+ * that supports both addition and removal of elements. This particular implementation follows
+ * the Add-Wins strategy, meaning that in case of conflicting add and remove operations,
+ * the add operation takes precedence. The merge operation of two OR-Sets ensures that
+ * elements added at any replica are eventually observed at all replicas. Removed elements,
+ * once observed, are never reintroduced.
+ * This OR-Set implementation provides methods for adding elements, removing elements,
+ * checking for element existence, retrieving the set of elements, comparing with other OR-Sets,
+ * and merging with another OR-Set to create a new OR-Set containing all unique elements
+ * from both sets.
+ *
+ * @author itakurah (Niklas Hoefflin) (https://github.com/itakurah)
+ * @see Conflict-free_replicated_data_type
+ * @see itakurah (Niklas Hoefflin)
+ */
+
+public class ORSet {
+
+ private final Set> elements;
+ private final Set> tombstones;
+
+ /**
+ * Constructs an empty OR-Set.
+ */
+ public ORSet() {
+ this.elements = new HashSet<>();
+ this.tombstones = new HashSet<>();
+ }
+
+ /**
+ * Checks if the set contains the specified element.
+ *
+ * @param element the element to check for
+ * @return true if the set contains the element, false otherwise
+ */
+ public boolean contains(T element) {
+ return elements.stream().anyMatch(pair -> pair.getElement().equals(element));
+ }
+
+ /**
+ * Retrieves the elements in the set.
+ *
+ * @return a set containing the elements
+ */
+ public Set elements() {
+ Set result = new HashSet<>();
+ elements.forEach(pair -> result.add(pair.getElement()));
+ return result;
+ }
+
+ /**
+ * Adds the specified element to the set.
+ *
+ * @param element the element to add
+ */
+ public void add(T element) {
+ String n = prepare();
+ effect(element, n);
+ }
+
+ /**
+ * Removes the specified element from the set.
+ *
+ * @param element the element to remove
+ */
+ public void remove(T element) {
+ Set> pairsToRemove = prepare(element);
+ effect(pairsToRemove);
+ }
+
+ /**
+ * Collect all pairs with the specified element.
+ *
+ * @param element the element to collect pairs for
+ * @return a set of pairs with the specified element to be removed
+ */
+ private Set> prepare(T element) {
+ Set> pairsToRemove = new HashSet<>();
+ for (Pair pair : elements) {
+ if (pair.getElement().equals(element)) {
+ pairsToRemove.add(pair);
+ }
+ }
+ return pairsToRemove;
+ }
+
+ /**
+ * Generates a unique tag for the element.
+ *
+ * @return the unique tag
+ */
+ private String prepare() {
+ return generateUniqueTag();
+ }
+
+ /**
+ * Adds the element with the specified unique tag to the set.
+ *
+ * @param element the element to add
+ * @param n the unique tag associated with the element
+ */
+ private void effect(T element, String n) {
+ Pair pair = new Pair<>(element, n);
+ elements.add(pair);
+ elements.removeAll(tombstones);
+ }
+
+ /**
+ * Removes the specified pairs from the set.
+ *
+ * @param pairsToRemove the pairs to remove
+ */
+ private void effect(Set> pairsToRemove) {
+ elements.removeAll(pairsToRemove);
+ tombstones.addAll(pairsToRemove);
+ }
+
+ /**
+ * Generates a unique tag.
+ *
+ * @return the unique tag
+ */
+ private String generateUniqueTag() {
+ return UUID.randomUUID().toString();
+ }
+
+ /**
+ * Compares this Add-Wins OR-Set with another OR-Set to check if elements and tombstones are a subset.
+ *
+ * @param other the other OR-Set to compare
+ * @return true if the sets are subset, false otherwise
+ */
+ public boolean compare(ORSet other) {
+ Set> union = new HashSet<>(elements);
+ union.addAll(tombstones);
+
+ Set> otherUnion = new HashSet<>(other.elements);
+ otherUnion.addAll(other.tombstones);
+
+ return otherUnion.containsAll(union) && other.tombstones.containsAll(tombstones);
+ }
+
+ /**
+ * Merges this Add-Wins OR-Set with another OR-Set.
+ *
+ * @param other the other OR-Set to merge
+ */
+ public void merge(ORSet other) {
+ elements.removeAll(other.tombstones);
+ other.elements.removeAll(tombstones);
+ elements.addAll(other.elements);
+ tombstones.addAll(other.tombstones);
+ }
+
+ /**
+ * Represents a pair containing an element and a unique tag.
+ *
+ * @param the type of the element in the pair
+ */
+ public static class Pair {
+ private final T element;
+ private final String uniqueTag;
+
+ /**
+ * Constructs a pair with the specified element and unique tag.
+ *
+ * @param element the element in the pair
+ * @param uniqueTag the unique tag associated with the element
+ */
+ public Pair(T element, String uniqueTag) {
+ this.element = element;
+ this.uniqueTag = uniqueTag;
+ }
+
+ /**
+ * Gets the element from the pair.
+ *
+ * @return the element
+ */
+ public T getElement() {
+ return element;
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java
new file mode 100644
index 000000000000..f12c38f174dc
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java
@@ -0,0 +1,86 @@
+package com.thealgorithms.datastructures.crdt;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.Set;
+import org.junit.jupiter.api.Test;
+
+class ORSetTest {
+
+ @Test
+ void testContains() {
+ ORSet orSet = new ORSet<>();
+ orSet.add("A");
+ assertTrue(orSet.contains("A"));
+ }
+
+ @Test
+ void testAdd() {
+ ORSet orSet = new ORSet<>();
+ orSet.add("A");
+ assertTrue(orSet.contains("A"));
+ }
+
+ @Test
+ void testRemove() {
+ ORSet orSet = new ORSet<>();
+ orSet.add("A");
+ orSet.add("A");
+ orSet.remove("A");
+ assertFalse(orSet.contains("A"));
+ }
+
+ @Test
+ void testElements() {
+ ORSet orSet = new ORSet<>();
+ orSet.add("A");
+ orSet.add("B");
+ assertEquals(Set.of("A", "B"), orSet.elements());
+ }
+
+ @Test
+ void testCompareEqualSets() {
+ ORSet orSet1 = new ORSet<>();
+ ORSet orSet2 = new ORSet<>();
+
+ orSet1.add("A");
+ orSet2.add("A");
+ orSet2.add("B");
+ orSet2.add("C");
+ orSet2.remove("C");
+ orSet1.merge(orSet2);
+ orSet2.merge(orSet1);
+ orSet2.remove("B");
+
+ assertTrue(orSet1.compare(orSet2));
+ }
+
+ @Test
+ void testCompareDifferentSets() {
+ ORSet orSet1 = new ORSet<>();
+ ORSet orSet2 = new ORSet<>();
+
+ orSet1.add("A");
+ orSet2.add("B");
+
+ assertFalse(orSet1.compare(orSet2));
+ }
+
+ @Test
+ void testMerge() {
+ ORSet orSet1 = new ORSet<>();
+ ORSet orSet2 = new ORSet<>();
+
+ orSet1.add("A");
+ orSet1.add("A");
+ orSet1.add("B");
+ orSet1.remove("B");
+ orSet2.add("B");
+ orSet2.add("C");
+ orSet2.remove("C");
+ orSet1.merge(orSet2);
+
+ assertTrue(orSet1.contains("A"));
+ assertTrue(orSet1.contains("B"));
+ }
+}
From 7ece806cf5cae7c3531f2eb54c56cf33fed2e579 Mon Sep 17 00:00:00 2001
From: aryan1165 <111041731+aryan1165@users.noreply.github.com>
Date: Tue, 26 Dec 2023 03:54:28 +0530
Subject: [PATCH 0081/1151] Remove duplicate file of Simple Substitution Cipher
(fixes #4494) (#4495)
---
DIRECTORY.md | 2 -
.../ciphers/SimpleSubstitutionCipher.java | 83 -------------------
.../ciphers/SimpleSubstitutionCipherTest.java | 48 -----------
3 files changed, 133 deletions(-)
delete mode 100644 src/main/java/com/thealgorithms/ciphers/SimpleSubstitutionCipher.java
delete mode 100644 src/test/java/com/thealgorithms/ciphers/SimpleSubstitutionCipherTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index b769250e4749..fd50b2914cff 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -48,7 +48,6 @@
* [ProductCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ProductCipher.java)
* [RSA](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/RSA.java)
* [SimpleSubCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java)
- * [SimpleSubstitutionCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/SimpleSubstitutionCipher.java)
* [Vigenere](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Vigenere.java)
* conversions
* [AnyBaseToAnyBase](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java)
@@ -596,7 +595,6 @@
* [PolybiusTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PolybiusTest.java)
* [RSATest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/RSATest.java)
* [SimpleSubCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java)
- * [SimpleSubstitutionCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/SimpleSubstitutionCipherTest.java)
* [VigenereTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/VigenereTest.java)
* conversions
* [BinaryToDecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/BinaryToDecimalTest.java)
diff --git a/src/main/java/com/thealgorithms/ciphers/SimpleSubstitutionCipher.java b/src/main/java/com/thealgorithms/ciphers/SimpleSubstitutionCipher.java
deleted file mode 100644
index 6ce3c564abc7..000000000000
--- a/src/main/java/com/thealgorithms/ciphers/SimpleSubstitutionCipher.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.thealgorithms.ciphers;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * The simple substitution cipher is a cipher that has been in use for many
- * hundreds of years (an excellent history is given in Simon Singhs 'the Code
- * Book'). It basically consists of substituting every plaintext character for a
- * different ciphertext character. It differs from the Caesar cipher in that the
- * cipher alphabet is not simply the alphabet shifted, it is completely jumbled.
- *
- * @author Hassan Elseoudy
- */
-public class SimpleSubstitutionCipher {
-
- /**
- * Encrypt text by replacing each element with its opposite character.
- *
- * @return Encrypted message
- */
- public static String encode(String message, String cipherSmall) {
- StringBuilder encoded = new StringBuilder();
-
- // This map is used to encode
- Map cipherMap = new HashMap<>();
-
- char beginSmallLetter = 'a';
- char beginCapitalLetter = 'A';
-
- cipherSmall = cipherSmall.toLowerCase();
- String cipherCapital = cipherSmall.toUpperCase();
-
- // To handle Small and Capital letters
- for (int i = 0; i < cipherSmall.length(); i++) {
- cipherMap.put(beginSmallLetter++, cipherSmall.charAt(i));
- cipherMap.put(beginCapitalLetter++, cipherCapital.charAt(i));
- }
-
- for (int i = 0; i < message.length(); i++) {
- if (Character.isAlphabetic(message.charAt(i))) {
- encoded.append(cipherMap.get(message.charAt(i)));
- } else {
- encoded.append(message.charAt(i));
- }
- }
-
- return encoded.toString();
- }
-
- /**
- * Decrypt message by replacing each element with its opposite character in
- * cipher.
- *
- * @return message
- */
- public static String decode(String encryptedMessage, String cipherSmall) {
- StringBuilder decoded = new StringBuilder();
-
- Map cipherMap = new HashMap<>();
-
- char beginSmallLetter = 'a';
- char beginCapitalLetter = 'A';
-
- cipherSmall = cipherSmall.toLowerCase();
- String cipherCapital = cipherSmall.toUpperCase();
-
- for (int i = 0; i < cipherSmall.length(); i++) {
- cipherMap.put(cipherSmall.charAt(i), beginSmallLetter++);
- cipherMap.put(cipherCapital.charAt(i), beginCapitalLetter++);
- }
-
- for (int i = 0; i < encryptedMessage.length(); i++) {
- if (Character.isAlphabetic(encryptedMessage.charAt(i))) {
- decoded.append(cipherMap.get(encryptedMessage.charAt(i)));
- } else {
- decoded.append(encryptedMessage.charAt(i));
- }
- }
-
- return decoded.toString();
- }
-}
diff --git a/src/test/java/com/thealgorithms/ciphers/SimpleSubstitutionCipherTest.java b/src/test/java/com/thealgorithms/ciphers/SimpleSubstitutionCipherTest.java
deleted file mode 100644
index f7cace2e08aa..000000000000
--- a/src/test/java/com/thealgorithms/ciphers/SimpleSubstitutionCipherTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.thealgorithms.ciphers;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import org.junit.jupiter.api.Test;
-
-public class SimpleSubstitutionCipherTest {
-
- @Test
- void testEncode() {
- // Given
- String message = "HELLOWORLD";
- String key = "phqgiumeaylnofdxjkrcvstzwb";
-
- // When
- String actual = SimpleSubstitutionCipher.encode(message, key);
-
- // Then
- assertEquals("EINNDTDKNG", actual);
- }
-
- @Test
- void testDecode() {
- // Given
- String message = "EINNDTDKNG";
- String key = "phqgiumeaylnofdxjkrcvstzwb";
-
- // When
- String actual = SimpleSubstitutionCipher.decode(message, key);
-
- // Then
- assertEquals("HELLOWORLD", actual);
- }
-
- @Test
- void testIsTextTheSameAfterEncodeAndDecode() {
- // Given
- String text = "HELLOWORLD";
- String key = "phqgiumeaylnofdxjkrcvstzwb";
-
- // When
- String encodedText = SimpleSubstitutionCipher.encode(text, key);
- String decodedText = SimpleSubstitutionCipher.decode(encodedText, key);
-
- // Then
- assertEquals(text, decodedText);
- }
-}
From a7d140a43e03821728f919f2402b006ae985cfa5 Mon Sep 17 00:00:00 2001
From: Nishant Jain <121454072+inishantjain@users.noreply.github.com>
Date: Tue, 2 Jan 2024 23:48:01 +0530
Subject: [PATCH 0082/1151] Add Set Kth Bit (#4990)
---
.../bitmanipulation/SetKthBit.java | 22 ++++++++++++++++++
.../bitmanipulation/SetKthBitTest.java | 23 +++++++++++++++++++
2 files changed, 45 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/bitmanipulation/SetKthBit.java
create mode 100644 src/test/java/com/thealgorithms/bitmanipulation/SetKthBitTest.java
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/SetKthBit.java b/src/main/java/com/thealgorithms/bitmanipulation/SetKthBit.java
new file mode 100644
index 000000000000..3c4e50d1d38d
--- /dev/null
+++ b/src/main/java/com/thealgorithms/bitmanipulation/SetKthBit.java
@@ -0,0 +1,22 @@
+package com.thealgorithms.bitmanipulation;
+
+/***
+ * Sets the kth bit of a given integer to 1
+ * e.g. setting 3rd bit in binary of 17 (binary 10001) gives 25 (binary 11001)
+ * @author inishantjain
+ */
+
+public class SetKthBit {
+ /**
+ * Sets the kth bit of a given integer.
+ *
+ * @param num The original integer.
+ * @param k The position of the bit to set (0-based index).
+ * @return The integer with the kth bit set.
+ */
+ public static int setKthBit(int num, int k) {
+ int mask = 1 << k;
+ num = num | mask;
+ return num;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/bitmanipulation/SetKthBitTest.java b/src/test/java/com/thealgorithms/bitmanipulation/SetKthBitTest.java
new file mode 100644
index 000000000000..35d5fa35da54
--- /dev/null
+++ b/src/test/java/com/thealgorithms/bitmanipulation/SetKthBitTest.java
@@ -0,0 +1,23 @@
+package com.thealgorithms.bitmanipulation;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+class SetKthBitTest {
+
+ @Test
+ void testSetKthBit() {
+ // Test case: Setting the 0th bit in 5 (binary 101)
+ assertEquals(5, SetKthBit.setKthBit(5, 0));
+
+ // Test case: Setting the 2nd bit in 10 (binary 1010)
+ assertEquals(14, SetKthBit.setKthBit(10, 2));
+
+ // Test case: Setting the 3rd bit in 15 (binary 1111)
+ assertEquals(15, SetKthBit.setKthBit(15, 3));
+
+ // Test case: Setting the 1st bit in 0 (binary 0)
+ assertEquals(2, SetKthBit.setKthBit(0, 1));
+ }
+}
From 9bef5a169c2295eee0c377db1f5afa0141bceb79 Mon Sep 17 00:00:00 2001
From: Govind Gupta <102366719+Govind516@users.noreply.github.com>
Date: Wed, 3 Jan 2024 18:44:38 +0530
Subject: [PATCH 0083/1151] Add Playfair Cipher (#4988)
---
DIRECTORY.md | 4 +
.../thealgorithms/ciphers/PlayfairCipher.java | 128 ++++++++++++++++++
.../thealgorithms/ciphers/PlayfairTest.java | 37 +++++
3 files changed, 169 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java
create mode 100644 src/test/java/com/thealgorithms/ciphers/PlayfairTest.java
diff --git a/DIRECTORY.md b/DIRECTORY.md
index fd50b2914cff..b621216da7f1 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -27,6 +27,7 @@
* [NonRepeatingNumberFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java)
* [NumbersDifferentSigns](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java)
* [ReverseBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java)
+ * [SetKthBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SetKthBit.java)
* [SingleBitOperations](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java)
* ciphers
* a5
@@ -44,6 +45,7 @@
* [ColumnarTranspositionCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java)
* [DES](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/DES.java)
* [HillCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/HillCipher.java)
+ * [PlayfairCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java)
* [Polybius](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Polybius.java)
* [ProductCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ProductCipher.java)
* [RSA](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/RSA.java)
@@ -585,6 +587,7 @@
* [NonRepeatingNumberFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java)
* [NumbersDifferentSignsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java)
* [ReverseBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java)
+ * [SetKthBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SetKthBitTest.java)
* [SingleBitOperationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java)
* ciphers
* a5
@@ -592,6 +595,7 @@
* [BlowfishTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java)
* [CaesarTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/CaesarTest.java)
* [DESTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/DESTest.java)
+ * [PlayfairTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java)
* [PolybiusTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PolybiusTest.java)
* [RSATest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/RSATest.java)
* [SimpleSubCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java)
diff --git a/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java b/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java
new file mode 100644
index 000000000000..76ceb6dbce31
--- /dev/null
+++ b/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java
@@ -0,0 +1,128 @@
+package com.thealgorithms.ciphers;
+
+public class PlayfairCipher {
+
+ private char[][] matrix;
+ private String key;
+
+ public PlayfairCipher(String key) {
+ this.key = key;
+ generateMatrix();
+ }
+
+ public String encrypt(String plaintext) {
+ plaintext = prepareText(plaintext.replace("J", "I"));
+ StringBuilder ciphertext = new StringBuilder();
+ for (int i = 0; i < plaintext.length(); i += 2) {
+ char char1 = plaintext.charAt(i);
+ char char2 = plaintext.charAt(i + 1);
+ int[] pos1 = findPosition(char1);
+ int[] pos2 = findPosition(char2);
+ int row1 = pos1[0];
+ int col1 = pos1[1];
+ int row2 = pos2[0];
+ int col2 = pos2[1];
+ if (row1 == row2) {
+ ciphertext.append(matrix[row1][(col1 + 1) % 5]);
+ ciphertext.append(matrix[row2][(col2 + 1) % 5]);
+ } else if (col1 == col2) {
+ ciphertext.append(matrix[(row1 + 1) % 5][col1]);
+ ciphertext.append(matrix[(row2 + 1) % 5][col2]);
+ } else {
+ ciphertext.append(matrix[row1][col2]);
+ ciphertext.append(matrix[row2][col1]);
+ }
+ }
+ return ciphertext.toString();
+ }
+
+ public String decrypt(String ciphertext) {
+ StringBuilder plaintext = new StringBuilder();
+ for (int i = 0; i < ciphertext.length(); i += 2) {
+ char char1 = ciphertext.charAt(i);
+ char char2 = ciphertext.charAt(i + 1);
+ int[] pos1 = findPosition(char1);
+ int[] pos2 = findPosition(char2);
+ int row1 = pos1[0];
+ int col1 = pos1[1];
+ int row2 = pos2[0];
+ int col2 = pos2[1];
+ if (row1 == row2) {
+ plaintext.append(matrix[row1][(col1 + 4) % 5]);
+ plaintext.append(matrix[row2][(col2 + 4) % 5]);
+ } else if (col1 == col2) {
+ plaintext.append(matrix[(row1 + 4) % 5][col1]);
+ plaintext.append(matrix[(row2 + 4) % 5][col2]);
+ } else {
+ plaintext.append(matrix[row1][col2]);
+ plaintext.append(matrix[row2][col1]);
+ }
+ }
+ return plaintext.toString();
+ }
+
+ private void generateMatrix() {
+ String keyWithoutDuplicates = removeDuplicateChars(key + "ABCDEFGHIKLMNOPQRSTUVWXYZ");
+ matrix = new char[5][5];
+ int index = 0;
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 5; j++) {
+ matrix[i][j] = keyWithoutDuplicates.charAt(index);
+ index++;
+ }
+ }
+ }
+
+ private String removeDuplicateChars(String str) {
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < str.length(); i++) {
+ if (result.indexOf(String.valueOf(str.charAt(i))) == -1) {
+ result.append(str.charAt(i));
+ }
+ }
+ return result.toString();
+ }
+
+ private String prepareText(String text) {
+ text = text.toUpperCase().replaceAll("[^A-Z]", "");
+ StringBuilder preparedText = new StringBuilder();
+ char prevChar = '\0';
+ for (char c : text.toCharArray()) {
+ if (c != prevChar) {
+ preparedText.append(c);
+ prevChar = c;
+ } else {
+ preparedText.append('X').append(c);
+ prevChar = '\0';
+ }
+ }
+ if (preparedText.length() % 2 != 0) {
+ preparedText.append('X');
+ }
+ return preparedText.toString();
+ }
+
+ private int[] findPosition(char c) {
+ int[] pos = new int[2];
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 5; j++) {
+ if (matrix[i][j] == c) {
+ pos[0] = i;
+ pos[1] = j;
+ return pos;
+ }
+ }
+ }
+ return pos;
+ }
+
+ public void printMatrix() {
+ System.out.println("\nPlayfair Cipher Matrix:");
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 5; j++) {
+ System.out.print(matrix[i][j] + " ");
+ }
+ System.out.println();
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java b/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java
new file mode 100644
index 000000000000..5562241b48db
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java
@@ -0,0 +1,37 @@
+package com.thealgorithms.ciphers;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class PlayfairTest {
+
+ @Test
+ public void testEncryption() {
+ PlayfairCipher playfairCipher = new PlayfairCipher("KEYWORD");
+
+ String plaintext = "HELLO";
+ String encryptedText = playfairCipher.encrypt(plaintext);
+ assertEquals("GYIZSC", encryptedText);
+ }
+
+ @Test
+ public void testDecryption() {
+ PlayfairCipher playfairCipher = new PlayfairCipher("KEYWORD");
+
+ String encryptedText = "UDRIYP";
+ String decryptedText = playfairCipher.decrypt(encryptedText);
+ assertEquals("NEBFVH", decryptedText);
+ }
+
+ @Test
+ public void testEncryptionAndDecryption() {
+ PlayfairCipher playfairCipher = new PlayfairCipher("KEYWORD");
+
+ String plaintext = "PLAYFAIR";
+ String encryptedText = playfairCipher.encrypt(plaintext);
+ String decryptedText = playfairCipher.decrypt(encryptedText);
+
+ assertEquals(plaintext, decryptedText);
+ }
+}
From 6a0c0585e4530f0c9cfd207ffe825c5acc3f022f Mon Sep 17 00:00:00 2001
From: AthinaSw <152101068+AthinaSw@users.noreply.github.com>
Date: Wed, 3 Jan 2024 20:11:07 +0200
Subject: [PATCH 0084/1151] Add cross-correlation and auto-correlation (#4984)
---
.../thealgorithms/maths/AutoCorrelation.java | 55 ++++++++++++
.../thealgorithms/maths/CrossCorrelation.java | 87 +++++++++++++++++++
.../maths/AutoCorrelationTest.java | 37 ++++++++
.../maths/CrossCorrelationTest.java | 37 ++++++++
4 files changed, 216 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/maths/AutoCorrelation.java
create mode 100644 src/main/java/com/thealgorithms/maths/CrossCorrelation.java
create mode 100644 src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java
create mode 100644 src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java
diff --git a/src/main/java/com/thealgorithms/maths/AutoCorrelation.java b/src/main/java/com/thealgorithms/maths/AutoCorrelation.java
new file mode 100644
index 000000000000..5b38235bcd01
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/AutoCorrelation.java
@@ -0,0 +1,55 @@
+package com.thealgorithms.maths;
+
+/**
+ * Class for linear auto-correlation of a discrete signal
+ *
+ * @author Athina-Frederiki Swinkels
+ * @version 2.0
+ */
+
+public class AutoCorrelation {
+
+ /**
+ * Discrete linear auto-correlation function.
+ * Input and output signals have starting index 0.
+ *
+ * @param x The discrete signal
+ * @return The result of the auto-correlation of signals x. The result is also a signal.
+ */
+ public static double[] autoCorrelation(double[] x) {
+
+ /*
+ To find the auto-correlation of a discrete signal x, we perform cross-correlation between x signal and itself.
+ Here's an example:
+ x=[1,2,1,1]
+ y=[1,2,1,1]
+
+ i=0: [1,2,1,1]
+ [1,2,1,1] result[0]=1*1=1
+
+ i=1: [1,2,1,1]
+ [1,2,1,1] result[1]=1*1+2*1=3
+
+ i=2: [1,2,1,1]
+ [1,2,1,1] result[2]=1*2+2*1+1*1=5
+
+ i=3: [1,2,1,1]
+ [1,2,1,1] result[3]=1*1+2*2+1*1+1*1=7
+
+ i=4: [1,2,1,1]
+ [1,2,1,1] result[4]=2*1+1*2+1*1=5
+
+ i=5: [1,2,1,1]
+ [1,2,1,1] result[5]=1*1+1*2=3
+
+ i=1: [1,2,1,1]
+ [1,2,1,1] result[6]=1*1=1
+
+ result=[1,3,5,7,5,3,1]
+
+
+ */
+
+ return CrossCorrelation.crossCorrelation(x, x);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/maths/CrossCorrelation.java b/src/main/java/com/thealgorithms/maths/CrossCorrelation.java
new file mode 100644
index 000000000000..080e4ab7e74b
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/CrossCorrelation.java
@@ -0,0 +1,87 @@
+package com.thealgorithms.maths;
+
+/**
+ * Class for linear cross-correlation of two discrete signals
+ *
+ * @author Athina-Frederiki Swinkels
+ * @version 1.0
+ */
+
+public class CrossCorrelation {
+
+ /**
+ * Discrete linear cross-correlation function.
+ * Input and output signals have starting index 0.
+ *
+ * @param x The first discrete signal
+ * @param y The second discrete signal
+ * @return The result of the cross-correlation of signals x,y. The result is also a signal.
+ */
+ public static double[] crossCorrelation(double[] x, double[] y) {
+ // The result signal's length is the sum of the input signals' lengths minus 1
+ double[] result = new double[x.length + y.length - 1];
+ int N = result.length;
+
+ /*
+ To find the cross-correlation between 2 discrete signals x & y, we start by "placing" the second signal
+ y under the first signal x, shifted to the left so that the last value of y meets the first value of x
+ and for every new position (i++) of the result signal, we shift y signal one position to the right, until
+ the first y-value meets the last x-value. The result-value for each position is the sum of all x*y meeting
+ values.
+ Here's an example:
+ x=[1,2,1,1]
+ y=[1,1,2,1]
+
+ i=0: [1,2,1,1]
+ [1,1,2,1] result[0]=1*1=1
+
+ i=1: [1,2,1,1]
+ [1,1,2,1] result[1]=1*2+2*1=4
+
+ i=2: [1,2,1,1]
+ [1,1,2,1] result[2]=1*1+2*2+1*1=6
+
+ i=3: [1,2,1,1]
+ [1,1,2,1] result[3]=1*1+2*1+1*2+1*1=6
+
+ i=4: [1,2,1,1]
+ [1,1,2,1] result[4]=2*1+1*1+1*2=5
+
+ i=5: [1,2,1,1]
+ [1,1,2,1] result[5]=1*1+1*1=2
+
+ i=1: [1,2,1,1]
+ [1,1,2,1] result[6]=1*1=1
+
+ result=[1,4,6,6,5,2,1]
+
+
+
+
+ To find the result[i] value for each i:0->N-1, the positions of x-signal in which the 2 signals meet
+ are calculated: kMin<=k<=kMax.
+ The variable 'yStart' indicates the starting index of y in each sum calculation.
+ The variable 'count' increases the index of y-signal by 1, to move to the next value.
+ */
+ int yStart = y.length;
+ for (int i = 0; i < N; i++) {
+ result[i] = 0;
+
+ int kMin = Math.max(i - (y.length - 1), 0);
+ int kMax = Math.min(i, x.length - 1);
+
+ if (i < y.length) {
+ yStart--;
+ }
+
+ int count = 0;
+ for (int k = kMin; k <= kMax; k++) {
+ result[i] += x[k] * y[yStart + count];
+ count++;
+ }
+ }
+
+ // The calculated cross-correlation of x & y signals is returned here.
+ return result;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java b/src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java
new file mode 100644
index 000000000000..cacfe5904faa
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java
@@ -0,0 +1,37 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+/**
+ * Test class for AutoCorrelation class
+ *
+ * @author Athina-Frederiki Swinkels
+ * @version 2.0
+ */
+
+public class AutoCorrelationTest {
+
+ @ParameterizedTest
+ @CsvSource({"1;2;1;1, 1;3;5;7;5;3;1", "1;2;3, 3;8;14;8;3", "1.5;2.3;3.1;4.2, 6.3;14.31;23.6;34.79;23.6;14.31;6.3"})
+
+ public void testAutoCorrelationParameterized(String input, String expected) {
+ double[] array = convertStringToArray(input);
+ double[] expectedResult = convertStringToArray(expected);
+
+ double[] result = AutoCorrelation.autoCorrelation(array);
+
+ assertArrayEquals(expectedResult, result, 0.0001);
+ }
+
+ private double[] convertStringToArray(String input) {
+ String[] elements = input.split(";");
+ double[] result = new double[elements.length];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = Double.parseDouble(elements[i]);
+ }
+ return result;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java b/src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java
new file mode 100644
index 000000000000..a7e4f14fb3af
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java
@@ -0,0 +1,37 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+/**
+ * Test class for CrossCorrelation class
+ *
+ * @author Athina-Frederiki Swinkels
+ * @version 2.0
+ */
+public class CrossCorrelationTest {
+
+ @ParameterizedTest
+ @CsvSource({"1;2;1;1, 1;1;2;1, 1;4;6;6;5;2;1", "1;2;3, 1;2;3;4;5, 5;14;26;20;14;8;3", "1;2;3;4;5, 1;2;3, 3;8;14;20;26;14;5", "1.5;2.3;3.1;4.2, 1.1;2.2;3.3, 4.95;10.89;16.94;23.21;12.65;4.62"})
+
+ public void testCrossCorrelationParameterized(String input1, String input2, String expected) {
+ double[] array1 = convertStringToArray(input1);
+ double[] array2 = convertStringToArray(input2);
+ double[] expectedResult = convertStringToArray(expected);
+
+ double[] result = CrossCorrelation.crossCorrelation(array1, array2);
+
+ assertArrayEquals(expectedResult, result, 0.0001);
+ }
+
+ private double[] convertStringToArray(String input) {
+ String[] elements = input.split(";");
+ double[] result = new double[elements.length];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = Double.parseDouble(elements[i]);
+ }
+ return result;
+ }
+}
From 092ac5795bc2004c04032fc2b79ee892e2ffcb05 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Wed, 3 Jan 2024 23:28:59 +0100
Subject: [PATCH 0085/1151] Remove `SetKthBit` in favor of
`SingleBitOperations.setBit` (#4991)
---
.../bitmanipulation/SetKthBit.java | 22 ------
.../bitmanipulation/SetKthBitTest.java | 23 -------
.../SingleBitOperationsTest.java | 68 ++++++++++---------
3 files changed, 36 insertions(+), 77 deletions(-)
delete mode 100644 src/main/java/com/thealgorithms/bitmanipulation/SetKthBit.java
delete mode 100644 src/test/java/com/thealgorithms/bitmanipulation/SetKthBitTest.java
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/SetKthBit.java b/src/main/java/com/thealgorithms/bitmanipulation/SetKthBit.java
deleted file mode 100644
index 3c4e50d1d38d..000000000000
--- a/src/main/java/com/thealgorithms/bitmanipulation/SetKthBit.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.thealgorithms.bitmanipulation;
-
-/***
- * Sets the kth bit of a given integer to 1
- * e.g. setting 3rd bit in binary of 17 (binary 10001) gives 25 (binary 11001)
- * @author inishantjain
- */
-
-public class SetKthBit {
- /**
- * Sets the kth bit of a given integer.
- *
- * @param num The original integer.
- * @param k The position of the bit to set (0-based index).
- * @return The integer with the kth bit set.
- */
- public static int setKthBit(int num, int k) {
- int mask = 1 << k;
- num = num | mask;
- return num;
- }
-}
diff --git a/src/test/java/com/thealgorithms/bitmanipulation/SetKthBitTest.java b/src/test/java/com/thealgorithms/bitmanipulation/SetKthBitTest.java
deleted file mode 100644
index 35d5fa35da54..000000000000
--- a/src/test/java/com/thealgorithms/bitmanipulation/SetKthBitTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.thealgorithms.bitmanipulation;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import org.junit.jupiter.api.Test;
-
-class SetKthBitTest {
-
- @Test
- void testSetKthBit() {
- // Test case: Setting the 0th bit in 5 (binary 101)
- assertEquals(5, SetKthBit.setKthBit(5, 0));
-
- // Test case: Setting the 2nd bit in 10 (binary 1010)
- assertEquals(14, SetKthBit.setKthBit(10, 2));
-
- // Test case: Setting the 3rd bit in 15 (binary 1111)
- assertEquals(15, SetKthBit.setKthBit(15, 3));
-
- // Test case: Setting the 1st bit in 0 (binary 0)
- assertEquals(2, SetKthBit.setKthBit(0, 1));
- }
-}
diff --git a/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java b/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java
index a6bb76689ec8..9cac8d670a4a 100644
--- a/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java
+++ b/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java
@@ -1,32 +1,36 @@
-package com.thealgorithms.bitmanipulation;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import org.junit.jupiter.api.Test;
-
-public class SingleBitOperationsTest {
-
- @Test
- public void flipBitTest() {
- assertEquals(1, SingleBitOperations.flipBit(3, 1));
- assertEquals(11, SingleBitOperations.flipBit(3, 3));
- }
-
- @Test
- public void setBitTest() {
- assertEquals(5, SingleBitOperations.setBit(4, 0));
- assertEquals(4, SingleBitOperations.setBit(4, 2));
- }
-
- @Test
- public void clearBitTest() {
- assertEquals(5, SingleBitOperations.clearBit(7, 1));
- assertEquals(5, SingleBitOperations.clearBit(5, 1));
- }
-
- @Test
- public void getBitTest() {
- assertEquals(0, SingleBitOperations.getBit(6, 0));
- assertEquals(1, SingleBitOperations.getBit(7, 1));
- }
-}
+package com.thealgorithms.bitmanipulation;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class SingleBitOperationsTest {
+
+ @Test
+ public void flipBitTest() {
+ assertEquals(1, SingleBitOperations.flipBit(3, 1));
+ assertEquals(11, SingleBitOperations.flipBit(3, 3));
+ }
+
+ @Test
+ public void setBitTest() {
+ assertEquals(5, SingleBitOperations.setBit(4, 0));
+ assertEquals(4, SingleBitOperations.setBit(4, 2));
+ assertEquals(5, SingleBitOperations.setBit(5, 0));
+ assertEquals(14, SingleBitOperations.setBit(10, 2));
+ assertEquals(15, SingleBitOperations.setBit(15, 3));
+ assertEquals(2, SingleBitOperations.setBit(0, 1));
+ }
+
+ @Test
+ public void clearBitTest() {
+ assertEquals(5, SingleBitOperations.clearBit(7, 1));
+ assertEquals(5, SingleBitOperations.clearBit(5, 1));
+ }
+
+ @Test
+ public void getBitTest() {
+ assertEquals(0, SingleBitOperations.getBit(6, 0));
+ assertEquals(1, SingleBitOperations.getBit(7, 1));
+ }
+}
From 1ea95ffa928e42bda532380233a9667764dafdf5 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Thu, 4 Jan 2024 11:56:48 +0100
Subject: [PATCH 0086/1151] Cleanup `PerfectSquare` and its tests (#4992)
---
.../thealgorithms/maths/PerfectSquare.java | 14 ++-----
.../maths/PerfectSquareTest.java | 41 ++++++-------------
2 files changed, 16 insertions(+), 39 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/PerfectSquare.java b/src/main/java/com/thealgorithms/maths/PerfectSquare.java
index 702e62943d88..fbc7a6f19bd0 100644
--- a/src/main/java/com/thealgorithms/maths/PerfectSquare.java
+++ b/src/main/java/com/thealgorithms/maths/PerfectSquare.java
@@ -3,14 +3,8 @@
/**
* https://en.wikipedia.org/wiki/Perfect_square
*/
-public class PerfectSquare {
-
- public static void main(String[] args) {
- assert !isPerfectSquare(-1);
- assert !isPerfectSquare(3);
- assert !isPerfectSquare(5);
- assert isPerfectSquare(9);
- assert isPerfectSquare(100);
+public final class PerfectSquare {
+ private PerfectSquare() {
}
/**
@@ -20,8 +14,8 @@ public static void main(String[] args) {
* @return true if {@code number} is perfect square, otherwise
* false
*/
- public static boolean isPerfectSquare(int number) {
- int sqrt = (int) Math.sqrt(number);
+ public static boolean isPerfectSquare(final int number) {
+ final int sqrt = (int) Math.sqrt(number);
return sqrt * sqrt == number;
}
}
diff --git a/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java b/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java
index 487b477816fd..450ba972debe 100644
--- a/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java
+++ b/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java
@@ -1,38 +1,21 @@
package com.thealgorithms.maths;
-import static org.junit.jupiter.api.Assertions.*;
-
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
public class PerfectSquareTest {
-
- @Test
- public void TestPerfectSquareifiscorrect() {
- // Valid Partition
- int number = 9;
-
- boolean result = PerfectSquare.isPerfectSquare(number);
-
- assertTrue(result);
- }
-
- @Test
- public void TestPerfectSquareifisnotcorrect() {
- // Invalid Partition 1
- int number = 3;
-
- boolean result = PerfectSquare.isPerfectSquare(number);
-
- assertFalse(result);
+ @ParameterizedTest
+ @ValueSource(ints = {0, 1, 2 * 2, 3 * 3, 4 * 4, 5 * 5, 6 * 6, 7 * 7, 8 * 8, 9 * 9, 10 * 10, 11 * 11, 123 * 123})
+ void positiveTest(final int number) {
+ Assertions.assertTrue(PerfectSquare.isPerfectSquare(number));
}
- @Test
- public void TestPerfectSquareifisNegativeNumber() {
- // Invalid Partition 2
- int number = -10;
-
- boolean result = PerfectSquare.isPerfectSquare(number);
-
- assertFalse(result);
+ @ParameterizedTest
+ @ValueSource(ints = {-1, -2, -3, -4, -5, -100, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 17, 99, 101, 257, 999, 1001})
+ void negativeTest(final int number) {
+ Assertions.assertFalse(PerfectSquare.isPerfectSquare(number));
}
}
From 8930ab5b16ad3ab062c22004dbfc3da701bb85ef Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Fri, 5 Jan 2024 22:05:52 +0100
Subject: [PATCH 0087/1151] Cleanup `SumOfDigits` and its tests (#4994)
---
.../com/thealgorithms/maths/SumOfDigits.java | 35 +++++-----------
.../thealgorithms/maths/SumOfDigitsTest.java | 40 +++++++++----------
2 files changed, 31 insertions(+), 44 deletions(-)
diff --git a/src/main/java/com/thealgorithms/maths/SumOfDigits.java b/src/main/java/com/thealgorithms/maths/SumOfDigits.java
index 09b690facdb9..e5ec8a02025d 100644
--- a/src/main/java/com/thealgorithms/maths/SumOfDigits.java
+++ b/src/main/java/com/thealgorithms/maths/SumOfDigits.java
@@ -1,13 +1,7 @@
package com.thealgorithms.maths;
-public class SumOfDigits {
-
- public static void main(String[] args) {
- assert sumOfDigits(-123) == 6 && sumOfDigitsRecursion(-123) == 6 && sumOfDigitsFast(-123) == 6;
-
- assert sumOfDigits(0) == 0 && sumOfDigitsRecursion(0) == 0 && sumOfDigitsFast(0) == 0;
-
- assert sumOfDigits(12345) == 15 && sumOfDigitsRecursion(12345) == 15 && sumOfDigitsFast(12345) == 15;
+public final class SumOfDigits {
+ private SumOfDigits() {
}
/**
@@ -17,12 +11,12 @@ public static void main(String[] args) {
* @return sum of digits of given {@code number}
*/
public static int sumOfDigits(int number) {
- number = number < 0 ? -number : number;
- /* calculate abs value */
+ final int base = 10;
+ number = Math.abs(number);
int sum = 0;
while (number != 0) {
- sum += number % 10;
- number /= 10;
+ sum += number % base;
+ number /= base;
}
return sum;
}
@@ -34,9 +28,9 @@ public static int sumOfDigits(int number) {
* @return sum of digits of given {@code number}
*/
public static int sumOfDigitsRecursion(int number) {
- number = number < 0 ? -number : number;
- /* calculate abs value */
- return number < 10 ? number : number % 10 + sumOfDigitsRecursion(number / 10);
+ final int base = 10;
+ number = Math.abs(number);
+ return number < base ? number : number % base + sumOfDigitsRecursion(number / base);
}
/**
@@ -45,14 +39,7 @@ public static int sumOfDigitsRecursion(int number) {
* @param number the number contains digits
* @return sum of digits of given {@code number}
*/
- public static int sumOfDigitsFast(int number) {
- number = number < 0 ? -number : number;
- /* calculate abs value */
- char[] digits = (number + "").toCharArray();
- int sum = 0;
- for (int i = 0; i < digits.length; ++i) {
- sum += digits[i] - '0';
- }
- return sum;
+ public static int sumOfDigitsFast(final int number) {
+ return String.valueOf(Math.abs(number)).chars().map(c -> c - '0').reduce(0, Integer::sum);
}
}
diff --git a/src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java b/src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java
index 1c3b56b7ee5e..76aca44a2220 100644
--- a/src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java
+++ b/src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java
@@ -1,31 +1,31 @@
package com.thealgorithms.maths;
-import static org.junit.jupiter.api.Assertions.*;
-
-import org.junit.jupiter.api.Test;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
class SumOfDigitsTest {
+ @ParameterizedTest
+ @MethodSource("testCases")
+ void sumOfDigitsTest(final int expected, final int input) {
+ Assertions.assertEquals(expected, SumOfDigits.sumOfDigits(input));
+ }
- SumOfDigits SoD = new SumOfDigits();
-
- @Test
- void testZero() {
- assertEquals(0, SumOfDigits.sumOfDigits(0));
- assertEquals(0, SumOfDigits.sumOfDigitsRecursion(0));
- assertEquals(0, SumOfDigits.sumOfDigitsFast(0));
+ @ParameterizedTest
+ @MethodSource("testCases")
+ void sumOfDigitsRecursionTest(final int expected, final int input) {
+ Assertions.assertEquals(expected, SumOfDigits.sumOfDigitsRecursion(input));
}
- @Test
- void testPositive() {
- assertEquals(15, SumOfDigits.sumOfDigits(12345));
- assertEquals(15, SumOfDigits.sumOfDigitsRecursion(12345));
- assertEquals(15, SumOfDigits.sumOfDigitsFast(12345));
+ @ParameterizedTest
+ @MethodSource("testCases")
+ void sumOfDigitsFastTest(final int expected, final int input) {
+ Assertions.assertEquals(expected, SumOfDigits.sumOfDigitsFast(input));
}
- @Test
- void testNegative() {
- assertEquals(6, SumOfDigits.sumOfDigits(-123));
- assertEquals(6, SumOfDigits.sumOfDigitsRecursion(-123));
- assertEquals(6, SumOfDigits.sumOfDigitsFast(-123));
+ private static Stream testCases() {
+ return Stream.of(Arguments.of(0, 0), Arguments.of(1, 1), Arguments.of(15, 12345), Arguments.of(6, -123), Arguments.of(1, -100000), Arguments.of(8, 512));
}
}
From 704b5878b660535477370a8f2d8c9d5175169302 Mon Sep 17 00:00:00 2001
From: "Tung Bui (Leo)"
Date: Sun, 7 Jan 2024 19:20:43 +0700
Subject: [PATCH 0088/1151] Use Discord channel in stale issue/PR message
(#5004)
---
.github/workflows/stale.yml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 8fbb262b9e36..ee14629b2e41 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -8,10 +8,10 @@ jobs:
steps:
- uses: actions/stale@v4
with:
- stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
- close-issue-message: 'Please reopen this issue once you add more information and updates here. If this is not the case and you need some help, feel free to seek help from our [Gitter](https://gitter.im/TheAlgorithms) or ping one of the reviewers. Thank you for your contributions!'
- stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
- close-pr-message: 'Please reopen this pull request once you commit the changes requested or make improvements on the code. If this is not the case and you need some help, feel free to seek help from our [Gitter](https://gitter.im/TheAlgorithms) or ping one of the reviewers. Thank you for your contributions!'
+ stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution!'
+ close-issue-message: 'Please reopen this issue once you have made the required changes. If you need help, feel free to ask in our [Discord](https://the-algorithms.com/discord) server or ping one of the maintainers here. Thank you for your contribution!'
+ stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution!'
+ close-pr-message: 'Please reopen this pull request once you have made the required changes. If you need help, feel free to ask in our [Discord](https://the-algorithms.com/discord) server or ping one of the maintainers here. Thank you for your contribution!'
exempt-issue-labels: 'dont-close'
exempt-pr-labels: 'dont-close'
days-before-stale: 30
From 0c881e39f24152a47ba03d4580a5cc8a6d6a69bc Mon Sep 17 00:00:00 2001
From: Nishant Jain <121454072+inishantjain@users.noreply.github.com>
Date: Mon, 8 Jan 2024 19:04:36 +0530
Subject: [PATCH 0089/1151] Simplify minimizing lateness (#4999)
---
.../greedyalgorithms/MinimizingLateness.java | 43 +++++++++++++++
.../MinimizingLateness.java | 55 -------------------
.../minimizinglateness/lateness_data.txt | 7 ---
.../MinimizingLatenessTest.java | 43 +++++++++++++++
4 files changed, 86 insertions(+), 62 deletions(-)
create mode 100644 src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java
delete mode 100644 src/main/java/com/thealgorithms/minimizinglateness/MinimizingLateness.java
delete mode 100644 src/main/java/com/thealgorithms/minimizinglateness/lateness_data.txt
create mode 100644 src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java
diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java b/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java
new file mode 100644
index 000000000000..938ae79bb625
--- /dev/null
+++ b/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java
@@ -0,0 +1,43 @@
+package com.thealgorithms.greedyalgorithms;
+
+import java.util.Arrays;
+
+public class MinimizingLateness {
+
+ public static class Job {
+ String jobName;
+ int startTime = 0;
+ int lateness = 0;
+ int processingTime;
+ int deadline;
+
+ public Job(String jobName, int processingTime, int deadline) {
+ this.jobName = jobName;
+ this.processingTime = processingTime;
+ this.deadline = deadline;
+ }
+
+ public static Job of(String jobName, int processingTime, int deadline) {
+ return new Job(jobName, processingTime, deadline);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s, startTime: %d, endTime: %d, lateness: %d", jobName, startTime, processingTime + startTime, lateness);
+ }
+ }
+
+ static void calculateLateness(Job... jobs) {
+
+ // sort the jobs based on their deadline
+ Arrays.sort(jobs, (a, b) -> a.deadline - b.deadline);
+
+ int startTime = 0;
+
+ for (Job job : jobs) {
+ job.startTime = startTime;
+ startTime += job.processingTime;
+ job.lateness = Math.max(0, startTime - job.deadline); // if the job finishes before deadline the lateness is 0
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/minimizinglateness/MinimizingLateness.java b/src/main/java/com/thealgorithms/minimizinglateness/MinimizingLateness.java
deleted file mode 100644
index fc7eae6ae9fc..000000000000
--- a/src/main/java/com/thealgorithms/minimizinglateness/MinimizingLateness.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.thealgorithms.minimizinglateness;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.StringTokenizer;
-
-public class MinimizingLateness {
-
- private static class Schedule { // Schedule class
-
- int t = 0; // Time required for the operation to be performed
- int d = 0; // Time the job should be completed
- public Schedule(int t, int d) {
- this.t = t;
- this.d = d;
- }
- }
-
- public static void main(String[] args) throws IOException {
- StringTokenizer token;
-
- BufferedReader in = new BufferedReader(new FileReader("MinimizingLateness/lateness_data.txt"));
- String ch = in.readLine();
- if (ch == null || ch.isEmpty()) {
- in.close();
- return;
- }
- int indexCount = Integer.parseInt(ch);
- System.out.println("Input Data : ");
- System.out.println(indexCount); // number of operations
- Schedule[] array = new Schedule[indexCount]; // Create an array to hold the operation
- int i = 0;
- while ((ch = in.readLine()) != null) {
- token = new StringTokenizer(ch, " ");
- // Include the time required for the operation to be performed in the array and the time
- // it should be completed.
- array[i] = new Schedule(Integer.parseInt(token.nextToken()), Integer.parseInt(token.nextToken()));
- i++;
- System.out.println(array[i - 1].t + " " + array[i - 1].d);
- }
-
- int tryTime = 0; // Total time worked
- int lateness = 0; // Lateness
- for (int j = 0; j < indexCount - 1; j++) {
- tryTime = tryTime + array[j].t; // Add total work time
- // Lateness
- lateness = lateness + Math.max(0, tryTime - array[j].d);
- }
- System.out.println();
- System.out.println("Output Data : ");
- System.out.println(lateness);
- in.close();
- }
-}
diff --git a/src/main/java/com/thealgorithms/minimizinglateness/lateness_data.txt b/src/main/java/com/thealgorithms/minimizinglateness/lateness_data.txt
deleted file mode 100644
index e2bac0d1cbd0..000000000000
--- a/src/main/java/com/thealgorithms/minimizinglateness/lateness_data.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-6
-3 6
-2 8
-1 9
-4 9
-3 14
-2 15
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java
new file mode 100644
index 000000000000..04f6900d14db
--- /dev/null
+++ b/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java
@@ -0,0 +1,43 @@
+package com.thealgorithms.greedyalgorithms;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import com.thealgorithms.greedyalgorithms.MinimizingLateness.Job;
+import org.junit.jupiter.api.Test;
+
+public class MinimizingLatenessTest {
+
+ @Test
+ void testCalculateLateness() {
+ // Test case with three jobs
+ Job job1 = new Job("Job1", 4, 6);
+ Job job2 = new Job("Job2", 2, 8);
+ Job job3 = new Job("Job3", 1, 9);
+ Job job4 = new Job("Job4", 5, 9);
+ Job job5 = new Job("Job5", 4, 10);
+ Job job6 = new Job("Job6", 3, 5);
+
+ MinimizingLateness.calculateLateness(job1, job2, job3, job4, job5, job6);
+
+ // Check lateness for each job
+ assertEquals(6, job4.lateness);
+ assertEquals(0, job6.lateness);
+ assertEquals(1, job2.lateness);
+ }
+
+ @Test
+ void testCheckStartTime() {
+
+ Job job1 = new Job("Job1", 2, 5);
+ Job job2 = new Job("Job2", 1, 7);
+ Job job3 = new Job("Job3", 3, 8);
+ Job job4 = new Job("Job4", 2, 4);
+ Job job5 = new Job("Job5", 4, 10);
+
+ MinimizingLateness.calculateLateness(job1, job2, job3, job4, job5);
+
+ assertEquals(2, job1.startTime);
+ assertEquals(5, job3.startTime);
+ assertEquals(8, job5.startTime);
+ }
+}
From bb2fff0cbb73f91d2b7d43741add059cd219e0a2 Mon Sep 17 00:00:00 2001
From: Nishant Jain <121454072+inishantjain@users.noreply.github.com>
Date: Mon, 8 Jan 2024 19:11:14 +0530
Subject: [PATCH 0090/1151] Add package name (#5007)
---
.../com/thealgorithms/searches/PerfectBinarySearchTest.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java b/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java
index 0ba0b03b33b4..ca5829c54495 100644
--- a/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java
+++ b/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java
@@ -1,6 +1,7 @@
+package com.thealgorithms.searches;
+
import static org.junit.jupiter.api.Assertions.*;
-import com.thealgorithms.searches.PerfectBinarySearch;
import org.junit.jupiter.api.Test;
/**
From c403e0033198adb2b023d01296ea1e3fc7fc2620 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Mon, 8 Jan 2024 22:32:18 +0100
Subject: [PATCH 0091/1151] Use `GITHUB_ACTOR` in `git config` (#5009)
---
.github/workflows/update_directory.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/update_directory.yml b/.github/workflows/update_directory.yml
index 0530a0c267a9..3638e3529e0b 100644
--- a/.github/workflows/update_directory.yml
+++ b/.github/workflows/update_directory.yml
@@ -84,8 +84,8 @@ jobs:
- name: Update DIRECTORY.md
run: |
cat DIRECTORY.md
- git config --global user.name github-actions
- git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com'
+ git config --global user.name "$GITHUB_ACTOR"
+ git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com"
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
git add DIRECTORY.md
git commit -am "Update directory" || true
From 570f7e7ef6876a6a5b6a7caf63056680969e3c18 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Mon, 8 Jan 2024 22:44:32 +0100
Subject: [PATCH 0092/1151] Remove unused import (#5010)
---
.../java/com/thealgorithms/strings/ReverseWordsInStringTest.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java b/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java
index 44e397459349..7cab6aa7c698 100644
--- a/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java
+++ b/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java
@@ -2,7 +2,6 @@
import java.util.stream.Stream;
import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
From fd84b0b10e2e6d17b161e53586164948b69d3b75 Mon Sep 17 00:00:00 2001
From: mpousmali <115431039+mpousmali@users.noreply.github.com>
Date: Mon, 8 Jan 2024 23:48:11 +0200
Subject: [PATCH 0093/1151] Add SRTF Algorithm (#5011)
---
.gitpod.yml | 1 +
.../scheduling/SRTFScheduling.java | 69 +++++++++++++++++++
.../scheduling/SRTFSchedulingTest.java | 61 ++++++++++++++++
3 files changed, 131 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java
create mode 100644 src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java
diff --git a/.gitpod.yml b/.gitpod.yml
index 4a3944d0023d..21d69f6e2122 100644
--- a/.gitpod.yml
+++ b/.gitpod.yml
@@ -10,3 +10,4 @@ tasks:
vscode:
extensions:
- xaver.clang-format
+
diff --git a/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java b/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java
new file mode 100644
index 000000000000..ad8aeabacad8
--- /dev/null
+++ b/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java
@@ -0,0 +1,69 @@
+package com.thealgorithms.scheduling;
+
+import com.thealgorithms.devutils.entities.ProcessDetails;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of Shortest Remaining Time First Scheduling Algorithm.
+ * In the SRTF scheduling algorithm, the process with the smallest amount of time remaining until completion is selected to execute.
+ * Example:
+ * Consider the processes p1, p2 and the following table with info about their arrival and burst time:
+ * Process | Burst Time | Arrival Time
+ * P1 | 6 ms | 0 ms
+ * P2 | 2 ms | 1 ms
+ * In this example, P1 will be executed at time = 0 until time = 1 when P2 arrives. At time = 2, P2 will be executed until time = 4. At time 4, P2 is done, and P1 is executed again to be done.
+ * That's a simple example of how the algorithm works.
+ * More information you can find here -> https://en.wikipedia.org/wiki/Shortest_remaining_time
+ */
+public class SRTFScheduling {
+ protected List processes;
+ protected List ready;
+
+ /**
+ * Constructor
+ * @param processes ArrayList of ProcessDetails given as input
+ */
+ public SRTFScheduling(ArrayList processes) {
+ this.processes = new ArrayList<>();
+ ready = new ArrayList<>();
+ this.processes = processes;
+ }
+
+ public void evaluateScheduling() {
+ int time = 0, cr = 0; // cr=current running process, time= units of time
+ int n = processes.size();
+ int[] remainingTime = new int[n];
+
+ /* calculating remaining time of every process and total units of time */
+ for (int i = 0; i < n; i++) {
+ remainingTime[i] = processes.get(i).getBurstTime();
+ time += processes.get(i).getBurstTime();
+ }
+
+ /* if the first process doesn't arrive at 0, we have more units of time */
+ if (processes.get(0).getArrivalTime() != 0) {
+ time += processes.get(0).getArrivalTime();
+ }
+
+ /* printing id of the process which is executed at every unit of time */
+ // if the first process doesn't arrive at 0, we print only \n until it arrives
+ if (processes.get(0).getArrivalTime() != 0) {
+ for (int i = 0; i < processes.get(0).getArrivalTime(); i++) {
+ ready.add(null);
+ }
+ }
+
+ for (int i = processes.get(0).getArrivalTime(); i < time; i++) {
+ /* checking if there's a process with remaining time less than current running process.
+ If we find it, then it executes. */
+ for (int j = 0; j < n; j++) {
+ if (processes.get(j).getArrivalTime() <= i && (remainingTime[j] < remainingTime[cr] && remainingTime[j] > 0 || remainingTime[cr] == 0)) {
+ cr = j;
+ }
+ }
+ ready.add(processes.get(cr).getProcessId());
+ remainingTime[cr]--;
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java
new file mode 100644
index 000000000000..0cfe3d34f0ec
--- /dev/null
+++ b/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java
@@ -0,0 +1,61 @@
+package com.thealgorithms.scheduling;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import com.thealgorithms.devutils.entities.ProcessDetails;
+import java.util.ArrayList;
+import org.junit.jupiter.api.Test;
+
+class SRTFSchedulingTest {
+ ArrayList processes;
+
+ public void initialization() {
+ processes = new ArrayList<>();
+ processes.add(new ProcessDetails("4", 0, 3));
+ processes.add(new ProcessDetails("3", 1, 8));
+ processes.add(new ProcessDetails("1", 2, 6));
+ processes.add(new ProcessDetails("5", 4, 4));
+ processes.add(new ProcessDetails("2", 5, 2));
+ }
+
+ @Test
+ public void Constructor() {
+ initialization();
+ SRTFScheduling s = new SRTFScheduling(processes);
+ assertEquals(3, s.processes.get(0).getBurstTime());
+ assertEquals(8, s.processes.get(1).getBurstTime());
+ assertEquals(6, s.processes.get(2).getBurstTime());
+ assertEquals(4, s.processes.get(3).getBurstTime());
+ assertEquals(2, s.processes.get(4).getBurstTime());
+ }
+
+ @Test
+ void evaluateScheduling() {
+ initialization();
+ SRTFScheduling s = new SRTFScheduling(processes);
+ s.evaluateScheduling();
+ assertEquals("4", s.ready.get(0));
+ assertEquals("4", s.ready.get(1));
+ assertEquals("4", s.ready.get(2));
+ assertEquals("1", s.ready.get(3));
+ assertEquals("5", s.ready.get(4));
+ assertEquals("2", s.ready.get(5));
+ assertEquals("2", s.ready.get(6));
+ assertEquals("5", s.ready.get(7));
+ assertEquals("5", s.ready.get(8));
+ assertEquals("5", s.ready.get(9));
+ assertEquals("1", s.ready.get(10));
+ assertEquals("1", s.ready.get(11));
+ assertEquals("1", s.ready.get(12));
+ assertEquals("1", s.ready.get(13));
+ assertEquals("1", s.ready.get(14));
+ assertEquals("3", s.ready.get(15));
+ assertEquals("3", s.ready.get(16));
+ assertEquals("3", s.ready.get(17));
+ assertEquals("3", s.ready.get(18));
+ assertEquals("3", s.ready.get(19));
+ assertEquals("3", s.ready.get(20));
+ assertEquals("3", s.ready.get(21));
+ assertEquals("3", s.ready.get(22));
+ }
+}
From 19b7a22ec94987f9d6a0df2079249c11deb9b337 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Wed, 10 Jan 2024 19:31:38 +0100
Subject: [PATCH 0094/1151] Remove unused imports from `BoyerMooreTest` (#5012)
---
src/test/java/com/thealgorithms/others/BoyerMooreTest.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/test/java/com/thealgorithms/others/BoyerMooreTest.java b/src/test/java/com/thealgorithms/others/BoyerMooreTest.java
index b1497f7bc525..b6620793d267 100644
--- a/src/test/java/com/thealgorithms/others/BoyerMooreTest.java
+++ b/src/test/java/com/thealgorithms/others/BoyerMooreTest.java
@@ -1,9 +1,7 @@
package com.thealgorithms.others;
-import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.stream.Stream;
import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
From 8804cec9574badcdc1e690c6db1314a463c10458 Mon Sep 17 00:00:00 2001
From: Sarthak Chaudhary <86872379+SarthakChaudhary46@users.noreply.github.com>
Date: Sat, 13 Jan 2024 13:59:30 +0530
Subject: [PATCH 0095/1151] Feature/4638 array right rotation (#5014)
* Create ArrayRightRotationTest.java
* Create ArrayRightRotation.java
* The updated one
* The updated one
* Added the test cases
* Added new test cases!
* Update ArrayRightRotation.java
* Update ArrayRightRotationTest.java
---
.../others/ArrayRightRotation.java | 28 ++++++++++
.../others/ArrayRightRotationTest.java | 53 +++++++++++++++++++
2 files changed, 81 insertions(+)
create mode 100644 src/test/java/com/thealgorithms/others/ArrayRightRotation.java
create mode 100644 src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java
diff --git a/src/test/java/com/thealgorithms/others/ArrayRightRotation.java b/src/test/java/com/thealgorithms/others/ArrayRightRotation.java
new file mode 100644
index 000000000000..a78ef81f32a4
--- /dev/null
+++ b/src/test/java/com/thealgorithms/others/ArrayRightRotation.java
@@ -0,0 +1,28 @@
+package com.thealgorithms.others;
+
+public class ArrayRightRotation {
+ public static int[] rotateRight(int[] arr, int k) {
+ if (arr == null || arr.length == 0 || k < 0) {
+ throw new IllegalArgumentException("Invalid input");
+ }
+
+ int n = arr.length;
+ k = k % n; // Handle cases where k is larger than the array length
+
+ reverseArray(arr, 0, n - 1);
+ reverseArray(arr, 0, k - 1);
+ reverseArray(arr, k, n - 1);
+
+ return arr;
+ }
+
+ private static void reverseArray(int[] arr, int start, int end) {
+ while (start < end) {
+ int temp = arr[start];
+ arr[start] = arr[end];
+ arr[end] = temp;
+ start++;
+ end--;
+ }
+ }
+}
diff --git a/src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java b/src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java
new file mode 100644
index 000000000000..f132d56dd9cd
--- /dev/null
+++ b/src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java
@@ -0,0 +1,53 @@
+package com.thealgorithms.others;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+
+import org.junit.jupiter.api.Test;
+
+class ArrayRightRotationTest {
+
+ @Test
+ void testArrayRightRotation() {
+ int[] arr = {1, 2, 3, 4, 5, 6, 7};
+ int k = 3;
+ int[] expected = {5, 6, 7, 1, 2, 3, 4};
+ int[] result = ArrayRightRotation.rotateRight(arr, k);
+ assertArrayEquals(expected, result);
+ }
+
+ @Test
+ void testArrayRightRotationWithZeroSteps() {
+ int[] arr = {1, 2, 3, 4, 5, 6, 7};
+ int k = 0;
+ int[] expected = {1, 2, 3, 4, 5, 6, 7};
+ int[] result = ArrayRightRotation.rotateRight(arr, k);
+ assertArrayEquals(expected, result);
+ }
+
+ @Test
+ void testArrayRightRotationWithEqualSizeSteps() {
+ int[] arr = {1, 2, 3, 4, 5, 6, 7};
+ int k = arr.length;
+ int[] expected = {1, 2, 3, 4, 5, 6, 7};
+ int[] result = ArrayRightRotation.rotateRight(arr, k);
+ assertArrayEquals(expected, result);
+ }
+
+ @Test
+ void testArrayRightRotationWithLowerSizeSteps() {
+ int[] arr = {1, 2, 3, 4, 5, 6, 7};
+ int k = 2;
+ int[] expected = {6, 7, 1, 2, 3, 4, 5};
+ int[] result = ArrayRightRotation.rotateRight(arr, k);
+ assertArrayEquals(expected, result);
+ }
+
+ @Test
+ void testArrayRightRotationWithHigherSizeSteps() {
+ int[] arr = {1, 2, 3, 4, 5, 6, 7};
+ int k = 10;
+ int[] expected = {5, 6, 7, 1, 2, 3, 4};
+ int[] result = ArrayRightRotation.rotateRight(arr, k);
+ assertArrayEquals(expected, result);
+ }
+}
From 9426053f73d55efde9c3c601f9cf4f30a33ec673 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Sat, 13 Jan 2024 10:04:32 +0100
Subject: [PATCH 0096/1151] Remove unused import from `PowerOfTwoOrNotTest`
(#5015)
style: remove unused import from `PowerOfTwoOrNotTest.java`
---
src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java b/src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java
index df01d481ccd8..ac8d2be17d7c 100644
--- a/src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java
+++ b/src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java
@@ -3,7 +3,6 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import java.util.Map;
import org.junit.jupiter.api.Test;
public class PowerOfTwoOrNotTest {
From ac7152d757096d5a30e68b3864108e2843d0c2ed Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Sat, 13 Jan 2024 10:21:57 +0100
Subject: [PATCH 0097/1151] Remove unused imports from `PerfectSquareTest`
(#5016)
style: remove unused imports from `PerfectSquareTest`
---
src/test/java/com/thealgorithms/maths/PerfectSquareTest.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java b/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java
index 450ba972debe..08c96bc71f9b 100644
--- a/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java
+++ b/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java
@@ -1,8 +1,6 @@
package com.thealgorithms.maths;
-import java.util.stream.Stream;
import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
From 3528399b2e385bffcfe0a2fff27d2a866d04a77a Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Sat, 13 Jan 2024 10:26:44 +0100
Subject: [PATCH 0098/1151] Remove unused import from `JobSequencing` (#5017)
style: remove unused import from `JobSequencing`
---
.../java/com/thealgorithms/greedyalgorithms/JobSequencing.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java b/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java
index bf81e067bac1..4d2cf7c95a03 100644
--- a/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java
+++ b/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java
@@ -2,7 +2,6 @@
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
// Problem Link: https://en.wikipedia.org/wiki/Job-shop_scheduling
From a216cb8a59ad04b3cadcc156e69dea41f3d1b465 Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Sat, 13 Jan 2024 10:28:50 +0100
Subject: [PATCH 0099/1151] Remove unused import from `HashMapCuckooHashing`
(#5018)
style: remove unused import from `HashMapCuckooHashing`
---
.../datastructures/hashmap/hashing/HashMapCuckooHashing.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java
index 74b2527f925c..053751ebbc51 100644
--- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java
+++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java
@@ -1,6 +1,5 @@
package com.thealgorithms.datastructures.hashmap.hashing;
-import java.lang.Math;
import java.util.Objects;
/**
From 55f08cc0139579760964e786364e2239cc65a8d9 Mon Sep 17 00:00:00 2001
From: Bhishmadev Ghosh <111000117+bhishma620@users.noreply.github.com>
Date: Sat, 27 Jan 2024 00:00:26 +0530
Subject: [PATCH 0100/1151] Add tests `SumOfSubset` (#5021)
* Updated main and test
* removed
* style: reorder test cases
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../{Sum_Of_Subset.java => SumOfSubset.java} | 13 +------------
.../dynamicprogramming/SumOfSubsetTest.java | 17 +++++++++++++++++
2 files changed, 18 insertions(+), 12 deletions(-)
rename src/main/java/com/thealgorithms/dynamicprogramming/{Sum_Of_Subset.java => SumOfSubset.java} (54%)
create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/Sum_Of_Subset.java b/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java
similarity index 54%
rename from src/main/java/com/thealgorithms/dynamicprogramming/Sum_Of_Subset.java
rename to src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java
index 90c07889a57f..622f8b146d96 100644
--- a/src/main/java/com/thealgorithms/dynamicprogramming/Sum_Of_Subset.java
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java
@@ -1,17 +1,6 @@
package com.thealgorithms.dynamicprogramming;
-public class Sum_Of_Subset {
-
- public static void main(String[] args) {
- int[] arr = {7, 3, 2, 5, 8};
- int Key = 14;
-
- if (subsetSum(arr, arr.length - 1, Key)) {
- System.out.print("Yes, that sum exists");
- } else {
- System.out.print("Nope, that number does not exist");
- }
- }
+public class SumOfSubset {
public static boolean subsetSum(int[] arr, int num, int Key) {
if (Key == 0) {
diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java
new file mode 100644
index 000000000000..53c34937cbab
--- /dev/null
+++ b/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java
@@ -0,0 +1,17 @@
+package com.thealgorithms.dynamicprogramming;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+class SumOfSubsetTest {
+
+ @Test
+ void basicCheck() {
+ assertEquals(false, SumOfSubset.subsetSum(new int[] {1, 2, 7, 10, 9}, 4, 14));
+ assertEquals(false, SumOfSubset.subsetSum(new int[] {2, 15, 1, 6, 7}, 4, 4));
+ assertEquals(true, SumOfSubset.subsetSum(new int[] {7, 3, 2, 5, 8}, 4, 14));
+ assertEquals(true, SumOfSubset.subsetSum(new int[] {4, 3, 2, 1}, 3, 5));
+ assertEquals(true, SumOfSubset.subsetSum(new int[] {1, 7, 2, 9, 10}, 4, 13));
+ }
+}
From b99aeef6743fc718c53c5aa29141d4f9e9f01460 Mon Sep 17 00:00:00 2001
From: Debasish Biswas
Date: Mon, 29 Jan 2024 01:18:40 +0530
Subject: [PATCH 0101/1151] Remove debasishbsws from CODEOWNERS (#5033)
As I am not very active in this repository, I should step down from being a CodeOwner /cc @BamaCharanChhandogi @yanglbme
---
.github/CODEOWNERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 0706d623599a..a84f13be1047 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @yanglbme @debasishbsws @vil02 @BamaCharanChhandogi
+* @yanglbme @vil02 @BamaCharanChhandogi
From 14b3f45f9f32df108de5d0eace624f23d6bbe1bf Mon Sep 17 00:00:00 2001
From: VedantK <145242784+555vedant@users.noreply.github.com>
Date: Thu, 1 Feb 2024 13:55:31 +0530
Subject: [PATCH 0102/1151] Add `ExchangeSort` (#5029)
* added ExchangeSort and its testcases
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../com/thealgorithms/sorts/ExchangeSort.java | 47 +++++++++++++++++++
.../thealgorithms/sorts/ExchangeSortTest.java | 8 ++++
2 files changed, 55 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/sorts/ExchangeSort.java
create mode 100644 src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java
diff --git a/src/main/java/com/thealgorithms/sorts/ExchangeSort.java b/src/main/java/com/thealgorithms/sorts/ExchangeSort.java
new file mode 100644
index 000000000000..28303430950c
--- /dev/null
+++ b/src/main/java/com/thealgorithms/sorts/ExchangeSort.java
@@ -0,0 +1,47 @@
+package com.thealgorithms.sorts;
+
+/**
+ * ExchangeSort is an implementation of the Exchange Sort algorithm.
+ *
+ *
+ * Exchange sort works by comparing each element with all subsequent elements,
+ * swapping where needed, to ensure the correct placement of each element
+ * in the final sorted order. It iteratively performs this process for each
+ * element in the array. While it lacks the advantage of bubble sort in
+ * detecting sorted lists in one pass, it can be more efficient than bubble sort
+ * due to a constant factor (one less pass over the data to be sorted; half as
+ * many total comparisons) in worst-case scenarios.
+ *
+ *
+ *
+ * Reference: https://en.wikipedia.org/wiki/Sorting_algorithm#Exchange_sort
+ *
+ *
+ * @author 555vedant (Vedant Kasar)
+ */
+class ExchangeSort implements SortAlgorithm {
+ /**
+ * Implementation of Exchange Sort Algorithm
+ *
+ * @param array the array to be sorted.
+ * @param the type of elements in the array.
+ * @return the sorted array.
+ */
+ @Override
+ public > T[] sort(T[] array) {
+ for (int i = 0; i < array.length - 1; i++) {
+ for (int j = i + 1; j < array.length; j++) {
+ if (array[i].compareTo(array[j]) > 0) {
+ swap(array, i, j);
+ }
+ }
+ }
+ return array;
+ }
+
+ private void swap(T[] array, int i, int j) {
+ T temp = array[i];
+ array[i] = array[j];
+ array[j] = temp;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java b/src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java
new file mode 100644
index 000000000000..6c4271fa9e19
--- /dev/null
+++ b/src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java
@@ -0,0 +1,8 @@
+package com.thealgorithms.sorts;
+
+public class ExchangeSortTest extends SortingAlgorithmTest {
+ @Override
+ SortAlgorithm getSortAlgorithm() {
+ return new ExchangeSort();
+ }
+}
From 55cc562d64a0e7caa622d18a67f51cf79970f48e Mon Sep 17 00:00:00 2001
From: Piotr Idzik <65706193+vil02@users.noreply.github.com>
Date: Sun, 11 Feb 2024 22:21:08 +0100
Subject: [PATCH 0103/1151] chore: update `actions/checkout` to `v4` (#5036)
---
.github/workflows/codeql.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 482c8bc60527..cea50a26c19a 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -24,7 +24,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v3
From 47a9b1b647d890d3cce50cd21774f5c78c350782 Mon Sep 17 00:00:00 2001
From: straf10 <115450409+straf10@users.noreply.github.com>
Date: Mon, 12 Feb 2024 21:48:07 +0200
Subject: [PATCH 0104/1151] Add `WelshPowell` (Graph Colouring) (#5034)
* Welsh Powell Algorithm + Test
---------
Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
---
.../datastructures/graphs/WelshPowell.java | 113 ++++++++++++++++
.../graphs/WelshPowellTest.java | 124 ++++++++++++++++++
2 files changed, 237 insertions(+)
create mode 100644 src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java
create mode 100644 src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java
diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java b/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java
new file mode 100644
index 000000000000..3b823f02388d
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java
@@ -0,0 +1,113 @@
+package com.thealgorithms.datastructures.graphs;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.stream.IntStream;
+
+/*
+ * The Welsh-Powell algorithm is a graph coloring algorithm
+ * used for coloring a graph with the minimum number of colors.
+ * https://en.wikipedia.org/wiki/Graph_coloring
+ */
+
+public final class WelshPowell {
+ private static final int BLANK_COLOR = -1; // Representing uncolored state
+
+ private WelshPowell() {
+ }
+
+ static class Graph {
+ private HashSet[] adjacencyLists;
+
+ private Graph(int vertices) {
+ if (vertices < 0) {
+ throw new IllegalArgumentException("Number of vertices cannot be negative");
+ }
+
+ adjacencyLists = new HashSet[vertices];
+ Arrays.setAll(adjacencyLists, i -> new HashSet<>());
+ }
+
+ private void addEdge(int nodeA, int nodeB) {
+ validateVertex(nodeA);
+ validateVertex(nodeB);
+ if (nodeA == nodeB) {
+ throw new IllegalArgumentException("Self-loops are not allowed");
+ }
+ adjacencyLists[nodeA].add(nodeB);
+ adjacencyLists[nodeB].add(nodeA);
+ }
+
+ private void validateVertex(int vertex) {
+ if (vertex < 0 || vertex >= getNumVertices()) {
+ throw new IllegalArgumentException("Vertex " + vertex + " is out of bounds");
+ }
+ }
+
+ HashSet getAdjacencyList(int vertex) {
+ return adjacencyLists[vertex];
+ }
+
+ int getNumVertices() {
+ return adjacencyLists.length;
+ }
+ }
+
+ public static Graph makeGraph(int numberOfVertices, int[][] listOfEdges) {
+ Graph graph = new Graph(numberOfVertices);
+ for (int[] edge : listOfEdges) {
+ if (edge.length != 2) {
+ throw new IllegalArgumentException("Edge array must have exactly two elements");
+ }
+ graph.addEdge(edge[0], edge[1]);
+ }
+ return graph;
+ }
+
+ public static int[] findColoring(Graph graph) {
+ int[] colors = initializeColors(graph.getNumVertices());
+ Integer[] sortedVertices = getSortedNodes(graph);
+ for (int vertex : sortedVertices) {
+ if (isBlank(colors[vertex])) {
+ boolean[] usedColors = computeUsedColors(graph, vertex, colors);
+ final var newColor = firstUnusedColor(usedColors);
+ colors[vertex] = newColor;
+ Arrays.stream(sortedVertices).forEach(otherVertex -> {
+ if (isBlank(colors[otherVertex]) && !isAdjacentToColored(graph, otherVertex, colors)) {
+ colors[otherVertex] = newColor;
+ }
+ });
+ }
+ }
+ return colors;
+ }
+
+ private static boolean isBlank(int color) {
+ return color == BLANK_COLOR;
+ }
+
+ private static boolean isAdjacentToColored(Graph graph, int vertex, int[] colors) {
+ return graph.getAdjacencyList(vertex).stream().anyMatch(otherVertex -> !isBlank(colors[otherVertex]));
+ }
+
+ private static int[] initializeColors(int numberOfVertices) {
+ int[] colors = new int[numberOfVertices];
+ Arrays.fill(colors, BLANK_COLOR);
+ return colors;
+ }
+
+ private static Integer[] getSortedNodes(final Graph graph) {
+ return IntStream.range(0, graph.getNumVertices()).boxed().sorted(Comparator.comparingInt(v -> - graph.getAdjacencyList(v).size())).toArray(Integer[] ::new);
+ }
+
+ private static boolean[] computeUsedColors(final Graph graph, final int vertex, final int[] colors) {
+ boolean[] usedColors = new boolean[graph.getNumVertices()];
+ graph.getAdjacencyList(vertex).stream().map(neighbor -> colors[neighbor]).filter(color -> !isBlank(color)).forEach(color -> usedColors[color] = true);
+ return usedColors;
+ }
+
+ private static int firstUnusedColor(boolean[] usedColors) {
+ return IntStream.range(0, usedColors.length).filter(color -> !usedColors[color]).findFirst().getAsInt();
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java b/src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java
new file mode 100644
index 000000000000..b37657db5c05
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java
@@ -0,0 +1,124 @@
+package com.thealgorithms.datastructures.graphs;
+
+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 com.thealgorithms.datastructures.graphs.WelshPowell.Graph;
+import java.util.Arrays;
+import org.junit.jupiter.api.Test;
+
+class WelshPowellTest {
+
+ @Test
+ void testSimpleGraph() {
+ final var graph = WelshPowell.makeGraph(4, new int[][] {{0, 1}, {1, 2}, {2, 3}});
+ int[] colors = WelshPowell.findColoring(graph);
+ assertTrue(isColoringValid(graph, colors));
+ assertEquals(2, countDistinctColors(colors));
+ }
+
+ @Test
+ void testDisconnectedGraph() {
+ final var graph = WelshPowell.makeGraph(3, new int[][] {}); // No edges
+ int[] colors = WelshPowell.findColoring(graph);
+ assertTrue(isColoringValid(graph, colors));
+ assertEquals(1, countDistinctColors(colors));
+ }
+
+ @Test
+ void testCompleteGraph() {
+ final var graph = WelshPowell.makeGraph(3, new int[][] {{0, 1}, {1, 2}, {2, 0}});
+ int[] colors = WelshPowell.findColoring(graph);
+ assertTrue(isColoringValid(graph, colors));
+ assertEquals(3, countDistinctColors(colors));
+ }
+
+ // The following test originates from the following website : https://www.geeksforgeeks.org/welsh-powell-graph-colouring-algorithm/
+ @Test
+ void testComplexGraph() {
+ int[][] edges = {
+ {0, 7}, // A-H
+ {0, 1}, // A-B
+ {1, 3}, // B-D
+ {2, 3}, // C-D
+ {3, 8}, // D-I
+ {3, 10}, // D-K
+ {4, 10}, // E-K
+ {4, 5}, // E-F
+ {5, 6}, // F-G
+ {6, 10}, // G-K
+ {6, 7}, // G-H
+ {7, 8}, // H-I
+ {7, 9}, // H-J
+ {7, 10}, // H-K
+ {8, 9}, // I-J
+ {9, 10}, // J-K
+ };
+
+ final var graph = WelshPowell.makeGraph(11, edges); // 11 vertices from A (0) to K (10)
+ int[] colors = WelshPowell.findColoring(graph);
+
+ assertTrue(isColoringValid(graph, colors), "The coloring should be valid with no adjacent vertices sharing the same color.");
+ assertEquals(3, countDistinctColors(colors), "The chromatic number of the graph should be 3.");
+ }
+
+ @Test
+ void testNegativeVertices() {
+ assertThrows(IllegalArgumentException.class, () -> { WelshPowell.makeGraph(-1, new int[][] {}); }, "Number of vertices cannot be negative");
+ }
+
+ @Test
+ void testSelfLoop() {
+ assertThrows(IllegalArgumentException.class, () -> { WelshPowell.makeGraph(3, new int[][] {{0, 0}}); }, "Self-loops are not allowed");
+ }
+
+ @Test
+ void testInvalidVertex() {
+ assertThrows(IllegalArgumentException.class, () -> { WelshPowell.makeGraph(3, new int[][] {{0, 3}}); }, "Vertex out of bounds");
+ assertThrows(IllegalArgumentException.class, () -> { WelshPowell.makeGraph(3, new int[][] {{0, -1}}); }, "Vertex out of bounds");
+ }
+
+ @Test
+ void testInvalidEdgeArray() {
+ assertThrows(IllegalArgumentException.class, () -> { WelshPowell.makeGraph(3, new int[][] {{0}}); }, "Edge array must have exactly two elements");
+ }
+
+ @Test
+ void testWithPreColoredVertex() {
+ // Create a linear graph with 4 vertices and edges connecting them in sequence
+ final var graph = WelshPowell.makeGraph(4, new int[][] {{0, 1}, {1, 2}, {2, 3}});
+
+ // Apply the Welsh-Powell coloring algorithm to the graph
+ int[] colors = WelshPowell.findColoring(graph);
+
+ // Validate that the coloring is correct (no two adjacent vertices have the same color)
+ assertTrue(isColoringValid(graph, colors));
+
+ // Check if the algorithm has used at least 2 colors (expected for a linear graph)
+ assertTrue(countDistinctColors(colors) >= 2);
+
+ // Verify that all vertices have been assigned a color
+ for (int color : colors) {
+ assertTrue(color >= 0);
+ }
+ }
+
+ private boolean isColoringValid(Graph graph, int[] colors) {
+ if (Arrays.stream(colors).anyMatch(n -> n < 0)) {
+ return false;
+ }
+ for (int i = 0; i < graph.getNumVertices(); i++) {
+ for (int neighbor : graph.getAdjacencyList(i)) {
+ if (i != neighbor && colors[i] == colors[neighbor]) {
+ return false; // Adjacent vertices have the same color
+ }
+ }
+ }
+ return true; // No adjacent vertices share the same color
+ }
+
+ private int countDistinctColors(int[] colors) {
+ return (int) Arrays.stream(colors).distinct().count();
+ }
+}
From ab371843aca53ab802e21427d28de5a65577a694 Mon Sep 17 00:00:00 2001
From: SOZEL <80200848+TruongNhanNguyen@users.noreply.github.com>
Date: Wed, 13 Mar 2024 01:49:58 +0700
Subject: [PATCH 0105/1151] Close `Scanner` to avoid resource leak (#5077)
---
.../thealgorithms/ciphers/ProductCipher.java | 107 ++++++++---------
.../datastructures/graphs/BellmanFord.java | 109 +++++++++---------
.../datastructures/stacks/ReverseStack.java | 40 +++----
.../maths/NonRepeatingElement.java | 103 +++++++++--------
.../others/InsertDeleteInArray.java | 73 ++++++------
.../searches/RecursiveBinarySearch.java | 36 +++---
6 files changed, 243 insertions(+), 225 deletions(-)
diff --git a/src/main/java/com/thealgorithms/ciphers/ProductCipher.java b/src/main/java/com/thealgorithms/ciphers/ProductCipher.java
index c5ce8a9b157c..5b1d46fe9a9a 100644
--- a/src/main/java/com/thealgorithms/ciphers/ProductCipher.java
+++ b/src/main/java/com/thealgorithms/ciphers/ProductCipher.java
@@ -5,67 +5,68 @@
class ProductCipher {
public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- System.out.println("Enter the input to be encrypted: ");
- String substitutionInput = sc.nextLine();
- System.out.println(" ");
- System.out.println("Enter a number: ");
- int n = sc.nextInt();
+ try (Scanner sc = new Scanner(System.in)) {
+ System.out.println("Enter the input to be encrypted: ");
+ String substitutionInput = sc.nextLine();
+ System.out.println(" ");
+ System.out.println("Enter a number: ");
+ int n = sc.nextInt();
- // Substitution encryption
- StringBuffer substitutionOutput = new StringBuffer();
- for (int i = 0; i < substitutionInput.length(); i++) {
- char c = substitutionInput.charAt(i);
- substitutionOutput.append((char) (c + 5));
- }
- System.out.println(" ");
- System.out.println("Substituted text: ");
- System.out.println(substitutionOutput);
+ // Substitution encryption
+ StringBuffer substitutionOutput = new StringBuffer();
+ for (int i = 0; i < substitutionInput.length(); i++) {
+ char c = substitutionInput.charAt(i);
+ substitutionOutput.append((char) (c + 5));
+ }
+ System.out.println(" ");
+ System.out.println("Substituted text: ");
+ System.out.println(substitutionOutput);
- // Transposition encryption
- String transpositionInput = substitutionOutput.toString();
- int modulus;
- if ((modulus = transpositionInput.length() % n) != 0) {
- modulus = n - modulus;
+ // Transposition encryption
+ String transpositionInput = substitutionOutput.toString();
+ int modulus;
+ if ((modulus = transpositionInput.length() % n) != 0) {
+ modulus = n - modulus;
- for (; modulus != 0; modulus--) {
- transpositionInput += "/";
+ for (; modulus != 0; modulus--) {
+ transpositionInput += "/";
+ }
}
- }
- StringBuffer transpositionOutput = new StringBuffer();
- System.out.println(" ");
- System.out.println("Transposition Matrix: ");
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < transpositionInput.length() / n; j++) {
- char c = transpositionInput.charAt(i + (j * n));
- System.out.print(c);
- transpositionOutput.append(c);
+ StringBuffer transpositionOutput = new StringBuffer();
+ System.out.println(" ");
+ System.out.println("Transposition Matrix: ");
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < transpositionInput.length() / n; j++) {
+ char c = transpositionInput.charAt(i + (j * n));
+ System.out.print(c);
+ transpositionOutput.append(c);
+ }
+ System.out.println();
}
- System.out.println();
- }
- System.out.println(" ");
- System.out.println("Final encrypted text: ");
- System.out.println(transpositionOutput);
+ System.out.println(" ");
+ System.out.println("Final encrypted text: ");
+ System.out.println(transpositionOutput);
- // Transposition decryption
- n = transpositionOutput.length() / n;
- StringBuffer transpositionPlaintext = new StringBuffer();
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < transpositionOutput.length() / n; j++) {
- char c = transpositionOutput.charAt(i + (j * n));
- transpositionPlaintext.append(c);
+ // Transposition decryption
+ n = transpositionOutput.length() / n;
+ StringBuffer transpositionPlaintext = new StringBuffer();
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < transpositionOutput.length() / n; j++) {
+ char c = transpositionOutput.charAt(i + (j * n));
+ transpositionPlaintext.append(c);
+ }
}
- }
- // Substitution decryption
- StringBuffer plaintext = new StringBuffer();
- for (int i = 0; i < transpositionPlaintext.length(); i++) {
- char c = transpositionPlaintext.charAt(i);
- plaintext.append((char) (c - 5));
- }
+ // Substitution decryption
+ StringBuffer plaintext = new StringBuffer();
+ for (int i = 0; i < transpositionPlaintext.length(); i++) {
+ char c = transpositionPlaintext.charAt(i);
+ plaintext.append((char) (c - 5));
+ }
- System.out.println("Plaintext: ");
- System.out.println(plaintext);
- sc.close();
+ System.out.println("Plaintext: ");
+ System.out.println(plaintext);
+ sc.close();
+ }
}
}
diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java b/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java
index 8229c1fa947d..9f5022b44465 100644
--- a/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java
+++ b/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java
@@ -2,9 +2,13 @@
import java.util.*;
-class BellmanFord /*Implementation of Bellman ford to detect negative cycles. Graph accepts inputs
-in form of edges which have start vertex, end vertex and weights. Vertices should be labelled with a
-number between 0 and total number of vertices-1,both inclusive*/
+class BellmanFord /*
+ * Implementation of Bellman ford to detect negative cycles. Graph accepts
+ * inputs
+ * in form of edges which have start vertex, end vertex and weights. Vertices
+ * should be labelled with a
+ * number between 0 and total number of vertices-1,both inclusive
+ */
{
int vertex, edge;
@@ -36,7 +40,7 @@ public Edge(int a, int b, int c) {
/**
* @param p[] Parent array which shows updates in edges
- * @param i Current vertex under consideration
+ * @param i Current vertex under consideration
*/
void printPath(int[] p, int i) {
if (p[i] == -1) { // Found the path back to parent
@@ -52,64 +56,65 @@ public static void main(String[] args) {
}
public void go() { // shows distance to all vertices // Interactive run for understanding the
- // class first time. Assumes source vertex is 0 and
- Scanner sc = new Scanner(System.in); // Grab scanner object for user input
- int i, v, e, u, ve, w, j, neg = 0;
- System.out.println("Enter no. of vertices and edges please");
- v = sc.nextInt();
- e = sc.nextInt();
- Edge[] arr = new Edge[e]; // Array of edges
- System.out.println("Input edges");
- for (i = 0; i < e; i++) {
- u = sc.nextInt();
- ve = sc.nextInt();
- w = sc.nextInt();
- arr[i] = new Edge(u, ve, w);
- }
- int[] dist = new int[v]; // Distance array for holding the finalized shortest path distance
- // between source
- // and all vertices
- int[] p = new int[v]; // Parent array for holding the paths
- for (i = 0; i < v; i++) {
- dist[i] = Integer.MAX_VALUE; // Initializing distance values
- }
- dist[0] = 0;
- p[0] = -1;
- for (i = 0; i < v - 1; i++) {
+ try ( // class first time. Assumes source vertex is 0 and
+ Scanner sc = new Scanner(System.in)) {
+ int i, v, e, u, ve, w, j, neg = 0;
+ System.out.println("Enter no. of vertices and edges please");
+ v = sc.nextInt();
+ e = sc.nextInt();
+ Edge[] arr = new Edge[e]; // Array of edges
+ System.out.println("Input edges");
+ for (i = 0; i < e; i++) {
+ u = sc.nextInt();
+ ve = sc.nextInt();
+ w = sc.nextInt();
+ arr[i] = new Edge(u, ve, w);
+ }
+ int[] dist = new int[v]; // Distance array for holding the finalized shortest path distance
+ // between source
+ // and all vertices
+ int[] p = new int[v]; // Parent array for holding the paths
+ for (i = 0; i < v; i++) {
+ dist[i] = Integer.MAX_VALUE; // Initializing distance values
+ }
+ dist[0] = 0;
+ p[0] = -1;
+ for (i = 0; i < v - 1; i++) {
+ for (j = 0; j < e; j++) {
+ if (dist[arr[j].u] != Integer.MAX_VALUE && dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
+ dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update
+ p[arr[j].v] = arr[j].u;
+ }
+ }
+ }
+ // Final cycle for negative checking
for (j = 0; j < e; j++) {
if (dist[arr[j].u] != Integer.MAX_VALUE && dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
- dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update
- p[arr[j].v] = arr[j].u;
+ neg = 1;
+ System.out.println("Negative cycle");
+ break;
}
}
- }
- // Final cycle for negative checking
- for (j = 0; j < e; j++) {
- if (dist[arr[j].u] != Integer.MAX_VALUE && dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
- neg = 1;
- System.out.println("Negative cycle");
- break;
- }
- }
- if (neg == 0) { // Go ahead and show results of computation
- System.out.println("Distances are: ");
- for (i = 0; i < v; i++) {
- System.out.println(i + " " + dist[i]);
- }
- System.out.println("Path followed:");
- for (i = 0; i < v; i++) {
- System.out.print("0 ");
- printPath(p, i);
- System.out.println();
+ if (neg == 0) { // Go ahead and show results of computation
+ System.out.println("Distances are: ");
+ for (i = 0; i < v; i++) {
+ System.out.println(i + " " + dist[i]);
+ }
+ System.out.println("Path followed:");
+ for (i = 0; i < v; i++) {
+ System.out.print("0 ");
+ printPath(p, i);
+ System.out.println();
+ }
}
+ sc.close();
}
- sc.close();
}
/**
* @param source Starting vertex
- * @param end Ending vertex
- * @param Edge Array of edges
+ * @param end Ending vertex
+ * @param Edge Array of edges
*/
public void show(int source, int end,
Edge[] arr) { // be created by using addEdge() method and passed by calling getEdgeArray()
diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java b/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java
index f269d08b5678..c9d2ea05778b 100644
--- a/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java
+++ b/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java
@@ -11,21 +11,22 @@
public class ReverseStack {
public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- System.out.println("Enter the number of elements you wish to insert in the stack");
- int n = sc.nextInt();
- int i;
- Stack stack = new Stack();
- System.out.println("Enter the stack elements");
- for (i = 0; i < n; i++) {
- stack.push(sc.nextInt());
- }
- sc.close();
- reverseStack(stack);
- System.out.println("The reversed stack is:");
- while (!stack.isEmpty()) {
- System.out.print(stack.peek() + ",");
- stack.pop();
+ try (Scanner sc = new Scanner(System.in)) {
+ System.out.println("Enter the number of elements you wish to insert in the stack");
+ int n = sc.nextInt();
+ int i;
+ Stack stack = new Stack();
+ System.out.println("Enter the stack elements");
+ for (i = 0; i < n; i++) {
+ stack.push(sc.nextInt());
+ }
+ sc.close();
+ reverseStack(stack);
+ System.out.println("The reversed stack is:");
+ while (!stack.isEmpty()) {
+ System.out.print(stack.peek() + ",");
+ stack.pop();
+ }
}
}
@@ -48,16 +49,15 @@ private static void reverseStack(Stack stack) {
private static void insertAtBottom(Stack