dev.to staff

Posted on

# Daily Challenge #214 - Persistent Bugger

Write a function, `persistence`, that takes in a positive parameter `num` and returns its multiplicative persistence, which is the number of times you must multiply the digits in `num` until you reach a single digit.

### Examples

``` persistence(39) === 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit

persistence(999) === 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2

persistence(4) === 0 // because 4 is already a one-digit number
```

### Tests

persistence(5)
persistence(52)
persistence(377)

Good luck!

This challenge comes from joh_pot on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Valts Liepiņš • Edited

``````import Numeric (floatToDigits)

persistence :: Int -> Int
persistence = recurse 0
where
recurse d x
| x > 9 = recurse (d+1) . foldr (*) 1 . digits \$ x
| otherwise = d
digits = fst . floatToDigits 10 . fromIntegral
``````

Edit:
Inspired by other solutions I realized that I don't need to track recursion depth

``````import Numeric (floatToDigits)

persistence :: Int -> Int
persistence x
| x > 9 = 1 + (persistence . foldr (*) 1 . digits \$ x)
| otherwise = 0
where digits = fst . floatToDigits 10 . fromIntegral
``````

Oisín

Nice use of pointfree style!

Amin • Edited

TypeScript

``````"use strict";

/**
* Compute the multiplicative persistence of a number.
*
* @param {number} number The number to compute the persistence from.
*
* @throws {Error}      If the function is called with not exactly one argument.
* @throws {TypeError}  If the first argument is not an integer.
* @throws {RangeError} If the first argument is not greater than or equal to zero.
*
* @return {number} The persistence of the number.
*
* @example
* persistence(39);     // 3
* persistence(999);    // 4
* persistence(4);      // 0
*/
const persistence = (number: number, ...extraParameters: unknown[]): number => {
if (0 !== extraParameters.length) {
throw new RangeError("The function has not been called with exactly one argument.");
}

if (!Number.isInteger(number)) {
throw new TypeError("First argument is not an integer.");
}

if (0 > number) {
throw new RangeError("First argument is not greater than or equal to zero");
}

const characters = number.toString();

if (1 === characters.length) {
return 0;
}

return 1 + persistence([...characters].reduce((total, character) => total * parseInt(character), 1));
};
``````

molamk

Nice 👌

kesprit

My Swift solution :

``````extension BinaryInteger {
var digits: [Int] {
String(describing: self).compactMap { Int(String(\$0)) }
}

var persistence: Int {
self.digits.reduce(into: 1) { \$0 = \$0 * \$1 }
}
}

func persistence(number: Int) -> Int {
number > 9 ? 1 + persistence(number: number.persistence) : 0
}

persistence(number: 4) // Output: 0
persistence(number: 39) // Output: 3
persistence(number: 999) // Output: 4
persistence(number: 5) // Output: 0
persistence(number: 52) // Output: 2
persistence(number: 377) // Output: 4
``````

Vidit Sarkar

Python solution

``````from functools import reduce
persistence = lambda num: 0 if num < 10 else 1 + persistence(reduce(int.__mul__,map(int, str(num))))

print(persistence(39)) # output 3
print(persistence(999)) # output 4
print(persistence(4)) # output 0
print(persistence(5)) # output 0
print(persistence(52)) # output 2
print(persistence(377)) # output 4
``````

''

JS

``````const persistence = (num, result =0) => {
const str = `\${num}`
if(str.length === 1) return result;
const mult = str.split("").reduce((a,b) => a * b)
return persistence(mult , result + 1)
}
``````

Ahmedur Rahman Shovon

Python solution with test cases.

``````from functools import reduce

def persistence(n):
count = 0
while True:
if len(str(n)) == 1:
return count
n = reduce(lambda x, y: x*y, [int(i) for i in str(n)], 1)
count += 1

if __name__ == "__main__":
test_cases = [39, 999, 4, 5, 52, 377]
expected_results = [3, 4, 0, 0, 2, 4]
total_test_cases = len(test_cases)
for i in range(total_test_cases):
test_case = test_cases[i]
expected_result = expected_results[i]
result = persistence(test_case)
assert_message = "persistence({}) returns {}. Expected {}".format(
test_case, result, expected_result
)
assert result == expected_result, assert_message
print("Passed all {} test cases".format(total_test_cases))
``````

SavagePixie

Elixir

``````defmodule Challenge do
def persistence(n) do
n
|> Integer.digits
|> _persistence(0)
end
defp _persistence([ _ | [] ], x), do: x
defp _persistence(list, x) do
list
|> List.foldl(1, &(&1 * &2))
|> Integer.digits
|> _persistence(x + 1)
end
end
``````

Vidit Sarkar

C++ solution

``````/*
Recursion :
persistence(num) = 0 if num < 10
= [1 + persistence(multiplication of digits of num)] if num >= 10
*/

int persistence(int num){
// Given number is positive, so no need to check for negative numbers

// if number is already single digit return 0
if(num < 10)
return 0;

// get the multiplication of digits
int mul = 1;
while(num > 0){
mul *= (num%10);
num /= 10;
}

// return 1 + persistence(mul)
return 1 + persistence(mul);
}
``````

Aleksandr Hovhannisyan

Recursive JavaScript solution:

``````function persistence(num) {
const digits = `\${num}`.split("");
if (digits.length === 1) {
return 0;
}

const product = digits.reduce((product, digit) => {
return product * digit;
}, 1);

return 1 + persistence(product);
}
``````

Sabin Pandelovitch

JS solution

``````function persistance(num){
let n = num;
let count = 0;
while(n > 9){
count++;
n = [...String(n)].map(Number).reduce((a,v)=> a*v,1)
}
return count
}
``````

Darko P.