diff --git a/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java b/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java index eb9750f9ce08..99842e2f4f5e 100644 --- a/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java +++ b/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java @@ -4,23 +4,51 @@ import java.util.ArrayList; import java.util.List; +/** + * Utility class for identifying and working with Kaprekar Numbers. + *
+ * A Kaprekar number is a positive integer with the following property: + * If you square it, then split the resulting number into two parts (right part + * has same number of + * digits as the original number, left part has the remaining digits), and + * finally add the two + * parts together, you get the original number. + *
+ * For example: + *
+ * Note: The right part can have leading zeros, but must not be all zeros.
+ *
+ * @see Kaprekar Number
+ * - Wikipedia
+ * @author TheAlgorithms (https://github.com/TheAlgorithms)
+ */
public final class KaprekarNumbers {
private KaprekarNumbers() {
}
- /* This program demonstrates if a given number is Kaprekar Number or not.
- Kaprekar Number: A Kaprekar number is an n-digit number which its square can be split into
- two parts where the right part has n digits and sum of these parts is equal to the original
- number. */
-
- // Provides a list of kaprekarNumber in a range
- public static List
+ * The algorithm works as follows:
+ *
+ * Special handling is required for numbers whose squares contain zeros.
+ *
+ * @param num the number to check
+ * @return true if the number is a Kaprekar number, false otherwise
+ * @throws IllegalArgumentException if num is negative
+ */
public static boolean isKaprekarNumber(long num) {
+ if (num < 0) {
+ throw new IllegalArgumentException("Number must be non-negative. Given: " + num);
+ }
+
+ if (num == 0 || num == 1) {
+ return true;
+ }
+
String number = Long.toString(num);
BigInteger originalNumber = BigInteger.valueOf(num);
BigInteger numberSquared = originalNumber.multiply(originalNumber);
- if (number.length() == numberSquared.toString().length()) {
- return number.equals(numberSquared.toString());
- } else {
- BigInteger leftDigits1 = BigInteger.ZERO;
- BigInteger leftDigits2;
- if (numberSquared.toString().contains("0")) {
- leftDigits1 = new BigInteger(numberSquared.toString().substring(0, numberSquared.toString().indexOf("0")));
- }
- leftDigits2 = new BigInteger(numberSquared.toString().substring(0, (numberSquared.toString().length() - number.length())));
- BigInteger rightDigits = new BigInteger(numberSquared.toString().substring(numberSquared.toString().length() - number.length()));
- String x = leftDigits1.add(rightDigits).toString();
- String y = leftDigits2.add(rightDigits).toString();
- return (number.equals(x)) || (number.equals(y));
+ String squaredStr = numberSquared.toString();
+
+ // Special case: if the squared number has the same length as the original
+ if (number.length() == squaredStr.length()) {
+ return number.equals(squaredStr);
+ }
+
+ // Calculate the split position
+ int splitPos = squaredStr.length() - number.length();
+
+ // Split the squared number into left and right parts
+ String leftPart = squaredStr.substring(0, splitPos);
+ String rightPart = squaredStr.substring(splitPos);
+
+ // Parse the parts as BigInteger (handles empty left part as zero)
+ BigInteger leftNum = leftPart.isEmpty() ? BigInteger.ZERO : new BigInteger(leftPart);
+ BigInteger rightNum = new BigInteger(rightPart);
+
+ // Check if right part is all zeros (invalid for Kaprekar numbers except 1)
+ if (rightNum.equals(BigInteger.ZERO)) {
+ return false;
}
+
+ // Check if the sum equals the original number
+ return leftNum.add(rightNum).equals(originalNumber);
}
}
diff --git a/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java b/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java
index 05e58cf88e22..a3cd7500b30c 100644
--- a/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java
+++ b/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java
@@ -1,85 +1,188 @@
package com.thealgorithms.maths;
+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 static org.junit.jupiter.api.Assertions.assertTrue;
+import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
-public class KaprekarNumbersTest {
+/**
+ * Test class for {@link KaprekarNumbers}.
+ * Tests various Kaprekar numbers and edge cases to ensure full coverage.
+ */
+class KaprekarNumbersTest {
@Test
- void testFor1() {
+ void testZeroIsKaprekarNumber() {
+ assertTrue(KaprekarNumbers.isKaprekarNumber(0));
+ }
+
+ @Test
+ void testOneIsKaprekarNumber() {
assertTrue(KaprekarNumbers.isKaprekarNumber(1));
}
@Test
- void testFor45() {
+ void testNineIsKaprekarNumber() {
+ // 9^2 = 81, 8 + 1 = 9
+ assertTrue(KaprekarNumbers.isKaprekarNumber(9));
+ }
+
+ @Test
+ void testFortyFiveIsKaprekarNumber() {
+ // 45^2 = 2025, 20 + 25 = 45
assertTrue(KaprekarNumbers.isKaprekarNumber(45));
}
@Test
- void testFor297() {
+ void testFiftyFiveIsKaprekarNumber() {
+ // 55^2 = 3025, 30 + 25 = 55
+ assertTrue(KaprekarNumbers.isKaprekarNumber(55));
+ }
+
+ @Test
+ void testNinetyNineIsKaprekarNumber() {
+ // 99^2 = 9801, 98 + 01 = 99
+ assertTrue(KaprekarNumbers.isKaprekarNumber(99));
+ }
+
+ @Test
+ void testTwoNinetySevenIsKaprekarNumber() {
+ // 297^2 = 88209, 88 + 209 = 297
assertTrue(KaprekarNumbers.isKaprekarNumber(297));
}
@Test
- void testFor2223() {
+ void testSevenZeroThreeIsKaprekarNumber() {
+ // 703^2 = 494209, 494 + 209 = 703
+ assertTrue(KaprekarNumbers.isKaprekarNumber(703));
+ }
+
+ @Test
+ void testNineNineNineIsKaprekarNumber() {
+ // 999^2 = 998001, 998 + 001 = 999
+ assertTrue(KaprekarNumbers.isKaprekarNumber(999));
+ }
+
+ @Test
+ void testTwoTwoTwoThreeIsKaprekarNumber() {
+ // 2223^2 = 4941729, 4941 + 729 = 5670 (not directly obvious)
+ // Actually: 494 + 1729 = 2223
assertTrue(KaprekarNumbers.isKaprekarNumber(2223));
}
@Test
- void testFor857143() {
+ void testEightFiveSevenOneFortyThreeIsKaprekarNumber() {
assertTrue(KaprekarNumbers.isKaprekarNumber(857143));
}
@Test
- void testFor3() {
+ void testTwoIsNotKaprekarNumber() {
+ assertFalse(KaprekarNumbers.isKaprekarNumber(2));
+ }
+
+ @Test
+ void testThreeIsNotKaprekarNumber() {
assertFalse(KaprekarNumbers.isKaprekarNumber(3));
}
@Test
- void testFor26() {
+ void testTenIsNotKaprekarNumber() {
+ assertFalse(KaprekarNumbers.isKaprekarNumber(10));
+ }
+
+ @Test
+ void testTwentySixIsNotKaprekarNumber() {
assertFalse(KaprekarNumbers.isKaprekarNumber(26));
}
@Test
- void testFor98() {
+ void testNinetyEightIsNotKaprekarNumber() {
assertFalse(KaprekarNumbers.isKaprekarNumber(98));
}
@Test
- void testForRangeOfNumber() {
- try {
- List
+ *
+ *