Skip to content

Commit d86a9e3

Browse files
authored
Merge branch 'master' into lb_add_tests
2 parents 54bfd96 + 7326ab2 commit d86a9e3

15 files changed

+825
-122
lines changed

DIRECTORY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,11 +1017,14 @@
10171017
* [RabinKarpAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java)
10181018
* [RecursiveBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java)
10191019
* [RowColumnWiseSorted2dArrayBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java)
1020+
* [SaddlebackSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/SaddlebackSearchTest.java)
10201021
* [SearchInARowAndColWiseSortedMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrixTest.java)
10211022
* [SortOrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/SortOrderAgnosticBinarySearchTest.java)
10221023
* [SquareRootBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/SquareRootBinarySearchTest.java)
1024+
* [TernarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/TernarySearchTest.java)
10231025
* [TestSearchInARowAndColWiseSortedMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java)
10241026
* [UnionFindTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/UnionFindTest.java)
1027+
* [UpperBoundTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/UpperBoundTest.java)
10251028
* sorts
10261029
* [BeadSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BeadSortTest.java)
10271030
* [BinaryInsertionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.thealgorithms.dynamicprogramming;
2+
/*
3+
The Sum of Subset problem determines whether a subset of elements from a
4+
given array sums up to a specific target value.
5+
*/
6+
public final class SubsetSumSpaceOptimized {
7+
private SubsetSumSpaceOptimized() {
8+
}
9+
/**
10+
* This method checks whether the subset of an array
11+
* contains a given sum or not. This is an space
12+
* optimized solution using 1D boolean array
13+
* Time Complexity: O(n * sum), Space complexity: O(sum)
14+
*
15+
* @param arr An array containing integers
16+
* @param sum The target sum of the subset
17+
* @return True or False
18+
*/
19+
public static boolean isSubsetSum(int[] arr, int sum) {
20+
int n = arr.length;
21+
// Declare the boolean array with size sum + 1
22+
boolean[] dp = new boolean[sum + 1];
23+
24+
// Initialize the first element as true
25+
dp[0] = true;
26+
27+
// Find the subset sum using 1D array
28+
for (int i = 0; i < n; i++) {
29+
for (int j = sum; j >= arr[i]; j--) {
30+
dp[j] = dp[j] || dp[j - arr[i]];
31+
}
32+
}
33+
return dp[sum];
34+
}
35+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package com.thealgorithms.maths;
2+
3+
import java.util.Random;
4+
5+
/**
6+
* This class implements the Solovay-Strassen primality test,
7+
* which is a probabilistic algorithm to determine whether a number is prime.
8+
* The algorithm is based on properties of the Jacobi symbol and modular exponentiation.
9+
*
10+
* For more information, go to {@link https://en.wikipedia.org/wiki/Solovay%E2%80%93Strassen_primality_test}
11+
*/
12+
final class SolovayStrassenPrimalityTest {
13+
14+
private final Random random;
15+
16+
/**
17+
* Constructs a SolovayStrassenPrimalityTest instance with a specified seed for randomness.
18+
*
19+
* @param seed the seed for generating random numbers
20+
*/
21+
private SolovayStrassenPrimalityTest(int seed) {
22+
random = new Random(seed);
23+
}
24+
25+
/**
26+
* Factory method to create an instance of SolovayStrassenPrimalityTest.
27+
*
28+
* @param seed the seed for generating random numbers
29+
* @return a new instance of SolovayStrassenPrimalityTest
30+
*/
31+
public static SolovayStrassenPrimalityTest getSolovayStrassenPrimalityTest(int seed) {
32+
return new SolovayStrassenPrimalityTest(seed);
33+
}
34+
35+
/**
36+
* Calculates modular exponentiation using the method of exponentiation by squaring.
37+
*
38+
* @param base the base number
39+
* @param exponent the exponent
40+
* @param mod the modulus
41+
* @return (base^exponent) mod mod
42+
*/
43+
private static long calculateModularExponentiation(long base, long exponent, long mod) {
44+
long x = 1; // This will hold the result of (base^exponent) % mod
45+
long y = base; // This holds the current base value being squared
46+
47+
while (exponent > 0) {
48+
// If exponent is odd, multiply the current base (y) with x
49+
if (exponent % 2 == 1) {
50+
x = x * y % mod; // Update result with current base
51+
}
52+
// Square the base for the next iteration
53+
y = y * y % mod; // Update base to be y^2
54+
exponent = exponent / 2; // Halve the exponent for next iteration
55+
}
56+
57+
return x % mod; // Return final result after all iterations
58+
}
59+
60+
/**
61+
* Computes the Jacobi symbol (a/n), which is a generalization of the Legendre symbol.
62+
*
63+
* @param a the numerator
64+
* @param num the denominator (must be an odd positive integer)
65+
* @return the Jacobi symbol value: 1, -1, or 0
66+
*/
67+
public int calculateJacobi(long a, long num) {
68+
// Check if num is non-positive or even; Jacobi symbol is not defined in these cases
69+
if (num <= 0 || num % 2 == 0) {
70+
return 0;
71+
}
72+
73+
a = a % num; // Reduce a modulo num to simplify calculations
74+
int jacobi = 1; // Initialize Jacobi symbol value
75+
76+
while (a != 0) {
77+
// While a is even, reduce it and adjust jacobi based on properties of num
78+
while (a % 2 == 0) {
79+
a /= 2; // Divide a by 2 until it becomes odd
80+
long nMod8 = num % 8; // Get num modulo 8 to check conditions for jacobi adjustment
81+
if (nMod8 == 3 || nMod8 == 5) {
82+
jacobi = -jacobi; // Flip jacobi sign based on properties of num modulo 8
83+
}
84+
}
85+
86+
long temp = a; // Temporarily store value of a
87+
a = num; // Set a to be num for next iteration
88+
num = temp; // Set num to be previous value of a
89+
90+
// Adjust jacobi based on properties of both numbers when both are odd and congruent to 3 modulo 4
91+
if (a % 4 == 3 && num % 4 == 3) {
92+
jacobi = -jacobi; // Flip jacobi sign again based on congruences
93+
}
94+
95+
a = a % num; // Reduce a modulo num for next iteration of Jacobi computation
96+
}
97+
98+
return (num == 1) ? jacobi : 0; // If num reduces to 1, return jacobi value, otherwise return 0 (not defined)
99+
}
100+
101+
/**
102+
* Performs the Solovay-Strassen primality test on a given number.
103+
*
104+
* @param num the number to be tested for primality
105+
* @param iterations the number of iterations to run for accuracy
106+
* @return true if num is likely prime, false if it is composite
107+
*/
108+
public boolean solovayStrassen(long num, int iterations) {
109+
if (num <= 1) {
110+
return false; // Numbers <=1 are not prime by definition.
111+
}
112+
if (num <= 3) {
113+
return true; // Numbers <=3 are prime.
114+
}
115+
116+
for (int i = 0; i < iterations; i++) {
117+
long r = Math.abs(random.nextLong() % (num - 1)) + 2; // Generate a non-negative random number.
118+
long a = r % (num - 1) + 1; // Choose random 'a' in range [1, n-1].
119+
120+
long jacobi = (num + calculateJacobi(a, num)) % num;
121+
// Calculate Jacobi symbol and adjust it modulo n.
122+
123+
long mod = calculateModularExponentiation(a, (num - 1) / 2, num);
124+
// Calculate modular exponentiation: a^((n-1)/2) mod n.
125+
126+
if (jacobi == 0 || mod != jacobi) {
127+
return false; // If Jacobi symbol is zero or doesn't match modular result, n is composite.
128+
}
129+
}
130+
131+
return true; // If no contradictions found after all iterations, n is likely prime.
132+
}
133+
}

src/main/java/com/thealgorithms/searches/LinearSearchThread.java

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,57 @@
11
package com.thealgorithms.searches;
22

3-
import java.util.Scanner;
4-
3+
/**
4+
* LinearSearchThread is a multithreaded implementation of the linear search algorithm.
5+
* It creates multiple threads to search for a specific number in an array.
6+
*
7+
* <p>
8+
* The class generates an array of random integers, prompts the user to enter a number to search for,
9+
* and divides the array into four segments, each handled by a separate thread.
10+
* The threads run concurrently and search for the specified number within their designated segments.
11+
* Finally, it consolidates the results to determine if the number was found.
12+
* </p>
13+
*
14+
* <p>
15+
* Example usage:
16+
* 1. The program will output the generated array.
17+
* 2. The user will be prompted to input a number to search for.
18+
* 3. The program will display whether the number was found in the array.
19+
* </p>
20+
*/
521
public final class LinearSearchThread {
622
private LinearSearchThread() {
723
}
8-
9-
public static void main(String[] args) {
10-
int[] list = new int[200];
11-
for (int j = 0; j < list.length; j++) {
12-
list[j] = (int) (Math.random() * 100);
13-
}
14-
for (int y : list) {
15-
System.out.print(y + " ");
16-
}
17-
System.out.println();
18-
System.out.print("Enter number to search for: ");
19-
Scanner in = new Scanner(System.in);
20-
int x = in.nextInt();
21-
Searcher t = new Searcher(list, 0, 50, x);
22-
Searcher t1 = new Searcher(list, 50, 100, x);
23-
Searcher t2 = new Searcher(list, 100, 150, x);
24-
Searcher t3 = new Searcher(list, 150, 200, x);
25-
t.start();
26-
t1.start();
27-
t2.start();
28-
t3.start();
29-
try {
30-
t.join();
31-
t1.join();
32-
t2.join();
33-
t3.join();
34-
} catch (InterruptedException e) {
35-
}
36-
boolean found = t.getResult() || t1.getResult() || t2.getResult() || t3.getResult();
37-
System.out.println("Found = " + found);
38-
in.close();
39-
}
4024
}
4125

26+
/**
27+
* The Searcher class extends Thread and is responsible for searching for a specific
28+
* number in a segment of an array.
29+
*/
4230
class Searcher extends Thread {
31+
private final int[] arr; // The array to search in
32+
private final int left; // Starting index of the segment
33+
private final int right; // Ending index of the segment
34+
private final int x; // The number to search for
35+
private boolean found; // Result flag
4336

44-
private final int[] arr;
45-
private final int left;
46-
private final int right;
47-
private final int x;
48-
private boolean found;
49-
37+
/**
38+
* Constructor to initialize the Searcher.
39+
*
40+
* @param arr The array to search in
41+
* @param left The starting index of the segment
42+
* @param right The ending index of the segment
43+
* @param x The number to search for
44+
*/
5045
Searcher(int[] arr, int left, int right, int x) {
5146
this.arr = arr;
5247
this.left = left;
5348
this.right = right;
5449
this.x = x;
5550
}
5651

52+
/**
53+
* The run method for the thread, performing the linear search in its segment.
54+
*/
5755
@Override
5856
public void run() {
5957
int k = left;
@@ -65,6 +63,11 @@ public void run() {
6563
}
6664
}
6765

66+
/**
67+
* Returns whether the number was found in the segment.
68+
*
69+
* @return true if the number was found, false otherwise
70+
*/
6871
boolean getResult() {
6972
return found;
7073
}

src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ public Node(Node parent, boolean isPlayersTurn) {
3939
static final int WIN_SCORE = 10;
4040
static final int TIME_LIMIT = 500; // Time the algorithm will be running for (in milliseconds).
4141

42-
public static void main(String[] args) {
43-
MonteCarloTreeSearch mcts = new MonteCarloTreeSearch();
44-
45-
mcts.monteCarloTreeSearch(mcts.new Node(null, true));
46-
}
47-
4842
/**
4943
* Explores a game tree using Monte Carlo Tree Search (MCTS) and returns the
5044
* most promising node.
Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.thealgorithms.searches;
22

3-
import java.util.Scanner;
4-
53
/**
64
* Program to perform Saddleback Search Given a sorted 2D array(elements are
75
* sorted across every row and column, assuming ascending order) of size n*m we
@@ -27,10 +25,15 @@ private SaddlebackSearch() {
2725
* @param row the current row.
2826
* @param col the current column.
2927
* @param key the element that we want to search for.
28+
* @throws IllegalArgumentException if the array is empty.
3029
* @return The index(row and column) of the element if found. Else returns
3130
* -1 -1.
3231
*/
33-
private static int[] find(int[][] arr, int row, int col, int key) {
32+
static int[] find(int[][] arr, int row, int col, int key) {
33+
if (arr.length == 0) {
34+
throw new IllegalArgumentException("Array is empty");
35+
}
36+
3437
// array to store the answer row and column
3538
int[] ans = {-1, -1};
3639
if (row < 0 || col >= arr[row].length) {
@@ -47,30 +50,4 @@ else if (arr[row][col] > key) {
4750
// else we move right
4851
return find(arr, row, col + 1, key);
4952
}
50-
51-
/**
52-
* Main method
53-
*
54-
* @param args Command line arguments
55-
*/
56-
public static void main(String[] args) {
57-
// TODO Auto-generated method stub
58-
Scanner sc = new Scanner(System.in);
59-
int[][] arr;
60-
int i;
61-
int j;
62-
int rows = sc.nextInt();
63-
int col = sc.nextInt();
64-
arr = new int[rows][col];
65-
for (i = 0; i < rows; i++) {
66-
for (j = 0; j < col; j++) {
67-
arr[i][j] = sc.nextInt();
68-
}
69-
}
70-
int ele = sc.nextInt();
71-
// we start from bottom left corner
72-
int[] ans = find(arr, rows - 1, 0, ele);
73-
System.out.println(ans[0] + " " + ans[1]);
74-
sc.close();
75-
}
7653
}

src/main/java/com/thealgorithms/searches/TernarySearch.java

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package com.thealgorithms.searches;
22

33
import com.thealgorithms.devutils.searches.SearchAlgorithm;
4-
import java.util.Arrays;
5-
import java.util.Random;
6-
import java.util.stream.Stream;
74

85
/**
96
* A ternary search algorithm is a technique in computer science for finding the
@@ -60,23 +57,4 @@ private <T extends Comparable<T>> int ternarySearch(T[] arr, T key, int start, i
6057
return ternarySearch(arr, key, mid1, mid2);
6158
}
6259
}
63-
64-
public static void main(String[] args) {
65-
// just generate data
66-
Random r = new Random();
67-
int size = 100;
68-
int maxElement = 100000;
69-
Integer[] integers = Stream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(Integer[] ::new);
70-
71-
// the element that should be found
72-
Integer shouldBeFound = integers[r.nextInt(size - 1)];
73-
74-
TernarySearch search = new TernarySearch();
75-
int atIndex = search.find(integers, shouldBeFound);
76-
77-
System.out.printf("Should be found: %d. Found %d at index %d. An array length %d%n", shouldBeFound, integers[atIndex], atIndex, size);
78-
79-
int toCheck = Arrays.binarySearch(integers, shouldBeFound);
80-
System.out.printf("Found by system method at an index: %d. Is equal: %b%n", toCheck, toCheck == atIndex);
81-
}
8260
}

0 commit comments

Comments
 (0)