diff --git a/src/main/java/com/thealgorithms/maths/NumberPersistence.java b/src/main/java/com/thealgorithms/maths/NumberPersistence.java new file mode 100644 index 000000000000..9cc6667dca02 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/NumberPersistence.java @@ -0,0 +1,79 @@ +package com.thealgorithms.maths; + +/** + * A utility class for calculating the persistence of a number. + * + *

This class provides methods to calculate: + *

+ * + *

This class is final and cannot be instantiated. + * + * @see Wikipedia: Persistence of a number + */ +public final class NumberPersistence { + + // Private constructor to prevent instantiation + private NumberPersistence() { + } + + /** + * Calculates the multiplicative persistence of a given number. + * + *

Multiplicative persistence is the number of steps required to reduce a number to a single digit + * by multiplying its digits repeatedly. + * + * @param num the number to calculate persistence for; must be non-negative + * @return the multiplicative persistence of the number + * @throws IllegalArgumentException if the input number is negative + */ + public static int multiplicativePersistence(int num) { + if (num < 0) { + throw new IllegalArgumentException("multiplicativePersistence() does not accept negative values"); + } + + int steps = 0; + while (num >= 10) { + int product = 1; + int temp = num; + while (temp > 0) { + product *= temp % 10; + temp /= 10; + } + num = product; + steps++; + } + return steps; + } + + /** + * Calculates the additive persistence of a given number. + * + *

Additive persistence is the number of steps required to reduce a number to a single digit + * by summing its digits repeatedly. + * + * @param num the number to calculate persistence for; must be non-negative + * @return the additive persistence of the number + * @throws IllegalArgumentException if the input number is negative + */ + public static int additivePersistence(int num) { + if (num < 0) { + throw new IllegalArgumentException("additivePersistence() does not accept negative values"); + } + + int steps = 0; + while (num >= 10) { + int sum = 0; + int temp = num; + while (temp > 0) { + sum += temp % 10; + temp /= 10; + } + num = sum; + steps++; + } + return steps; + } +} diff --git a/src/test/java/com/thealgorithms/maths/NumberPersistenceTest.java b/src/test/java/com/thealgorithms/maths/NumberPersistenceTest.java new file mode 100644 index 000000000000..3f7e70167fc2 --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/NumberPersistenceTest.java @@ -0,0 +1,42 @@ +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.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; + +class NumberPersistenceTest { + + @ParameterizedTest(name = "multiplicativePersistence({0}) = {1}") + @CsvSource({"0, 0", "7, 0", "217, 2", "39, 3", "999, 4"}) + @DisplayName("Test multiplicative persistence with valid inputs") + void testMultiplicativePersistenceValid(int input, int expected) { + assertEquals(expected, NumberPersistence.multiplicativePersistence(input)); + } + + @ParameterizedTest(name = "multiplicativePersistence({0}) throws IllegalArgumentException") + @ValueSource(ints = {-1, -100, -9999}) + @DisplayName("Test multiplicative persistence with negative numbers") + void testMultiplicativePersistenceNegative(int input) { + Exception exception = assertThrows(IllegalArgumentException.class, () -> NumberPersistence.multiplicativePersistence(input)); + assertEquals("multiplicativePersistence() does not accept negative values", exception.getMessage()); + } + + @ParameterizedTest(name = "additivePersistence({0}) = {1}") + @CsvSource({"0, 0", "5, 0", "199, 3", "999, 2", "1234, 2"}) + @DisplayName("Test additive persistence with valid inputs") + void testAdditivePersistenceValid(int input, int expected) { + assertEquals(expected, NumberPersistence.additivePersistence(input)); + } + + @ParameterizedTest(name = "additivePersistence({0}) throws IllegalArgumentException") + @ValueSource(ints = {-1, -100, -9999}) + @DisplayName("Test additive persistence with negative numbers") + void testAdditivePersistenceNegative(int input) { + Exception exception = assertThrows(IllegalArgumentException.class, () -> NumberPersistence.additivePersistence(input)); + assertEquals("additivePersistence() does not accept negative values", exception.getMessage()); + } +}