Repository: TheAlgorithms/Java
Pull request #3260 (2022-09-10 07:27:28)

Add pollard rho algorithm
### **Describe your change:**

- [x] Add an algorithm?
- [ ] Fix a bug or typo in an existing algorithm?
- [ ] Documentation change?

#### References
Issue #3256 
<!-- Add any reference to previous pull-request or issue -->

### **Checklist:**

<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->

- [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
- [x] This pull request is all my own work -- I have not plagiarized.
- [x] I know that pull requests will not be merged if they fail the automated tests.
- [x] This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
- [x] All new Java files are placed inside an existing directory.
- [x] All filenames are in all uppercase characters with no spaces or dashes.
- [x] All functions and variable names follow Java naming conventions.
- [x] All new algorithms have a URL in its comments that points to Wikipedia or other similar explanation.
- [x] If this pull request resolves one or more open issues then the commit message contains `Fixes: #{$ISSUE_NO}`.



Patch:
diff --git a/src/main/java/com/thealgorithms/maths/PollardRho.java b/src/main/java/com/thealgorithms/maths/PollardRho.java
new file mode 100644
index 00000000..36e7116c
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/PollardRho.java
@@ -0,0 +1,74 @@
+package com.thealgorithms.maths;
+
+/*
+ * Java program for pollard rho algorithm
+ * The algorithm is used to factorize a number n = pq,
+ * where p is a non-trivial factor. 
+ * Pollard's rho algorithm is an algorithm for integer factorization
+ * and it takes as its inputs n, the integer to be factored; 
+ * and g(x), a polynomial in x computed modulo n.
+ * In the original algorithm, g(x) = ((x ^ 2) − 1) mod n,
+ * but nowadays it is more common to use g(x) = ((x ^ 2) + 1 ) mod n. 
+ * The output is either a non-trivial factor of n, or failure.
+ * It performs the following steps:
+ *     x ← 2
+ *     y ← 2
+ *     d ← 1
+
+ *     while d = 1:
+ *         x ← g(x)
+ *         y ← g(g(y))
+ *         d ← gcd(|x - y|, n)
+
+ *     if d = n: 
+ *         return failure
+ *     else:
+ *         return d
+
+ * Here x and y corresponds to xi and xj in the previous section. 
+ * Note that this algorithm may fail to find a nontrivial factor even when n is composite.
+ * In that case, the method can be tried again, using a starting value other than 2 or a different g(x)
+ * 
+ * Wikipedia: https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
+ * 
+ * Author: Akshay Dubey (https://github.com/itsAkshayDubey)
+ * 
+ * */
+public class PollardRho {
+	
+	/**
+	 * This method returns a polynomial in x computed modulo n
+	 *
+	 * @param base Integer base of the polynomial
+	 * @param modulus Integer is value which is to be used to perform modulo operation over the polynomial 
+	 * @return Integer (((base * base) - 1) % modulus)
+	 */
+	static int g(int base,int modulus) {
+		return ((base * base) - 1) % modulus;
+	}
+	
+	/**
+	 * This method returns a non-trivial factor of given integer number  
+	 *
+	 * @param number Integer is a integer value whose non-trivial factor is to be found
+	 * @return Integer non-trivial factor of number
+	 * @throws RuntimeException object if GCD of given number cannot be found
+	 */
+	static int pollardRho(int number) {
+		int x = 2, y = 2, d = 1;
+		while(d == 1) {
+			//tortoise move
+			x = g(x, number);
+			
+			//hare move
+			y = g(g(y, number), number);
+			
+			//check GCD of |x-y| and number
+			d = GCD.gcd(Math.abs(x - y), number);
+		}
+		if(d == number) {
+			throw new RuntimeException("GCD cannot be found.");
+		}
+		return d;
+	}
+}


Test patch:
diff --git a/src/test/java/com/thealgorithms/maths/PollardRhoTest.java b/src/test/java/com/thealgorithms/maths/PollardRhoTest.java
new file mode 100644
index 00000000..757ababa
--- /dev/null
+++ b/src/test/java/com/thealgorithms/maths/PollardRhoTest.java
@@ -0,0 +1,51 @@
+package com.thealgorithms.maths;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+class PollardRhoTest {
+
+	@Test
+	void testPollardRhoForNumber315MustReturn5() {
+		//given
+		int number = 315;
+		int expectedResult = 5;
+
+		//when
+		int actualResult = PollardRho.pollardRho(number);
+
+		//then
+		assertEquals(expectedResult, actualResult);
+	}
+
+	@Test
+	void testPollardRhoForNumber187MustReturn11() {
+		//given
+		int number = 187;
+		int expectedResult = 11;
+
+		//when
+		int actualResult = PollardRho.pollardRho(number);
+
+		//then
+		assertEquals(expectedResult, actualResult);
+	}
+
+	@Test
+	void testPollardRhoForNumber239MustThrowException() {
+		//given
+		int number = 239;
+		String expectedMessage = "GCD cannot be found.";
+
+		//when
+		Exception exception = assertThrows(RuntimeException.class, () -> {
+			PollardRho.pollardRho(number);
+		});
+		String actualMessage = exception.getMessage();
+
+		//then
+		assertEquals(expectedMessage, actualMessage);
+	}
+}