diff --git a/src/main/java/com/thealgorithms/maths/HappyNumber.java b/src/main/java/com/thealgorithms/maths/HappyNumber.java new file mode 100644 index 000000000000..bfe746953b33 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/HappyNumber.java @@ -0,0 +1,57 @@ +package com.thealgorithms.maths; + +/** + * A Happy Number is defined as a number which eventually reaches 1 when replaced + * by the sum of the squares of each digit. + * If it falls into a cycle that does not include 1, then it is not a happy number. + + * Example: + * 19 → 1² + 9² = 82 + * 82 → 8² + 2² = 68 + * 68 → 6² + 8² = 100 + * 100 → 1² + 0² + 0² = 1 → Happy Number! + */ +public final class HappyNumber { + + private HappyNumber() { + } + + /** + * Checks whether the given number is a Happy Number. + * Uses Floyd’s Cycle Detection algorithm (tortoise and hare method) + * to detect loops efficiently. + * + * @param n The number to check + * @return true if n is a Happy Number, false otherwise + */ + public static boolean isHappy(int n) { + int slow = n; + int fast = n; + + do { + slow = sumOfSquares(slow); // move 1 step + fast = sumOfSquares(sumOfSquares(fast)); // move 2 steps + } while (slow != fast); + + return slow == 1; // If cycle ends in 1 → Happy number + } + + /** + * Calculates the sum of squares of the digits of a number. + * + * Example: + * num = 82 → 8² + 2² = 64 + 4 = 68 + * + * @param num The number to calculate sum of squares of digits + * @return The sum of squares of the digits + */ + private static int sumOfSquares(int num) { + int sum = 0; + while (num > 0) { + int digit = num % 10; + sum += digit * digit; + num /= 10; + } + return sum; + } +} diff --git a/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java b/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java deleted file mode 100644 index 0ae1e451bc6a..000000000000 --- a/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.thealgorithms.others; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Scanner; -import java.util.Set; - -public final class HappyNumbersSeq { - private HappyNumbersSeq() { - } - - private static final Set CYCLE_NUMS = new HashSet<>(Arrays.asList(4, 16, 20, 37, 58, 145)); - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - System.out.print("Enter number: "); - int n = in.nextInt(); - while (n != 1 && !isSad(n)) { - System.out.print(n + " "); - n = sumSquares(n); - } - String res = n == 1 ? "1 Happy number" : "Sad number"; - System.out.println(res); - in.close(); - } - - private static int sumSquares(int n) { - int s = 0; - for (; n > 0; n /= 10) { - int r = n % 10; - s += r * r; - } - return s; - } - - private static boolean isSad(int n) { - return CYCLE_NUMS.contains(n); - } -} diff --git a/src/test/java/com/thealgorithms/maths/HappyNumberTest.java b/src/test/java/com/thealgorithms/maths/HappyNumberTest.java new file mode 100644 index 000000000000..4b7cb795406f --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/HappyNumberTest.java @@ -0,0 +1,32 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class HappyNumberTest { + + @Test + void testHappyNumbers() { + // Known happy numbers + assertTrue(HappyNumber.isHappy(1)); + assertTrue(HappyNumber.isHappy(7)); + assertTrue(HappyNumber.isHappy(19)); + assertTrue(HappyNumber.isHappy(100)); + } + + @Test + void testUnhappyNumbers() { + // Known unhappy numbers + assertFalse(HappyNumber.isHappy(2)); + assertFalse(HappyNumber.isHappy(4)); + assertFalse(HappyNumber.isHappy(20)); + } + + @Test + void testLargeNumber() { + // Just to check behavior with larger input + assertTrue(HappyNumber.isHappy(1000000)); // reduces to 1 eventually + } +}