Skip to content

Commit 6d51709

Browse files
Dev: Added NumberPersistence utility class to find multiplicative and additive persistance (#6612)
* Add NumberPersistence utility class with multiplicative and additive persistence methods * Fixed identified style issues
1 parent 7e29be3 commit 6d51709

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.thealgorithms.maths;
2+
3+
/**
4+
* A utility class for calculating the persistence of a number.
5+
*
6+
* <p>This class provides methods to calculate:
7+
* <ul>
8+
* <li>Multiplicative persistence: The number of steps required to reduce a number to a single digit by multiplying its digits.</li>
9+
* <li>Additive persistence: The number of steps required to reduce a number to a single digit by summing its digits.</li>
10+
* </ul>
11+
*
12+
* <p>This class is final and cannot be instantiated.
13+
*
14+
* @see <a href="https://en.wikipedia.org/wiki/Persistence_of_a_number">Wikipedia: Persistence of a number</a>
15+
*/
16+
public final class NumberPersistence {
17+
18+
// Private constructor to prevent instantiation
19+
private NumberPersistence() {
20+
}
21+
22+
/**
23+
* Calculates the multiplicative persistence of a given number.
24+
*
25+
* <p>Multiplicative persistence is the number of steps required to reduce a number to a single digit
26+
* by multiplying its digits repeatedly.
27+
*
28+
* @param num the number to calculate persistence for; must be non-negative
29+
* @return the multiplicative persistence of the number
30+
* @throws IllegalArgumentException if the input number is negative
31+
*/
32+
public static int multiplicativePersistence(int num) {
33+
if (num < 0) {
34+
throw new IllegalArgumentException("multiplicativePersistence() does not accept negative values");
35+
}
36+
37+
int steps = 0;
38+
while (num >= 10) {
39+
int product = 1;
40+
int temp = num;
41+
while (temp > 0) {
42+
product *= temp % 10;
43+
temp /= 10;
44+
}
45+
num = product;
46+
steps++;
47+
}
48+
return steps;
49+
}
50+
51+
/**
52+
* Calculates the additive persistence of a given number.
53+
*
54+
* <p>Additive persistence is the number of steps required to reduce a number to a single digit
55+
* by summing its digits repeatedly.
56+
*
57+
* @param num the number to calculate persistence for; must be non-negative
58+
* @return the additive persistence of the number
59+
* @throws IllegalArgumentException if the input number is negative
60+
*/
61+
public static int additivePersistence(int num) {
62+
if (num < 0) {
63+
throw new IllegalArgumentException("additivePersistence() does not accept negative values");
64+
}
65+
66+
int steps = 0;
67+
while (num >= 10) {
68+
int sum = 0;
69+
int temp = num;
70+
while (temp > 0) {
71+
sum += temp % 10;
72+
temp /= 10;
73+
}
74+
num = sum;
75+
steps++;
76+
}
77+
return steps;
78+
}
79+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.thealgorithms.maths;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
6+
import org.junit.jupiter.api.DisplayName;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.CsvSource;
9+
import org.junit.jupiter.params.provider.ValueSource;
10+
11+
class NumberPersistenceTest {
12+
13+
@ParameterizedTest(name = "multiplicativePersistence({0}) = {1}")
14+
@CsvSource({"0, 0", "7, 0", "217, 2", "39, 3", "999, 4"})
15+
@DisplayName("Test multiplicative persistence with valid inputs")
16+
void testMultiplicativePersistenceValid(int input, int expected) {
17+
assertEquals(expected, NumberPersistence.multiplicativePersistence(input));
18+
}
19+
20+
@ParameterizedTest(name = "multiplicativePersistence({0}) throws IllegalArgumentException")
21+
@ValueSource(ints = {-1, -100, -9999})
22+
@DisplayName("Test multiplicative persistence with negative numbers")
23+
void testMultiplicativePersistenceNegative(int input) {
24+
Exception exception = assertThrows(IllegalArgumentException.class, () -> NumberPersistence.multiplicativePersistence(input));
25+
assertEquals("multiplicativePersistence() does not accept negative values", exception.getMessage());
26+
}
27+
28+
@ParameterizedTest(name = "additivePersistence({0}) = {1}")
29+
@CsvSource({"0, 0", "5, 0", "199, 3", "999, 2", "1234, 2"})
30+
@DisplayName("Test additive persistence with valid inputs")
31+
void testAdditivePersistenceValid(int input, int expected) {
32+
assertEquals(expected, NumberPersistence.additivePersistence(input));
33+
}
34+
35+
@ParameterizedTest(name = "additivePersistence({0}) throws IllegalArgumentException")
36+
@ValueSource(ints = {-1, -100, -9999})
37+
@DisplayName("Test additive persistence with negative numbers")
38+
void testAdditivePersistenceNegative(int input) {
39+
Exception exception = assertThrows(IllegalArgumentException.class, () -> NumberPersistence.additivePersistence(input));
40+
assertEquals("additivePersistence() does not accept negative values", exception.getMessage());
41+
}
42+
}

0 commit comments

Comments
 (0)