Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions src/main/java/com/thealgorithms/maths/NumberPersistence.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.thealgorithms.maths;

/**
* A utility class for calculating the persistence of a number.
*
* <p>This class provides methods to calculate:
* <ul>
* <li>Multiplicative persistence: The number of steps required to reduce a number to a single digit by multiplying its digits.</li>
* <li>Additive persistence: The number of steps required to reduce a number to a single digit by summing its digits.</li>
* </ul>
*
* <p>This class is final and cannot be instantiated.
*
* @see <a href="https://en.wikipedia.org/wiki/Persistence_of_a_number">Wikipedia: Persistence of a number</a>
*/
public final class NumberPersistence {

// Private constructor to prevent instantiation
private NumberPersistence() {
}

/**
* Calculates the multiplicative persistence of a given number.
*
* <p>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.
*
* <p>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;
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}