2

Currently I'm going through the problems on CodeWars, and I'm stuck on the Persistent Bugger problem.

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.

For example:

persistence(39) # returns 3, because 39=27, 27=14, 14=4 # and 4 has only one digit persistence(999) # returns 4, because 999=729, 729=126, # 126=12, and finally 12=2

persistence(4) # returns 0, because 4 is already a one-digit number

I've narrowed down my problem to a recursive function, however I'm having trouble wrapping my head around how to return my iteration counter.

Currently it runs through the program and maintains an accurate count. When it ends up with a single digit value however, it returns to the persistence call, lowering my iteration every time.

def persistence(n, iter=0):
    chars = str(n)

    if n > 9:
        result = 1
        for y in chars:
            result = result * int(y)
        iter += 1
        persistence(result, iter)

    else:
        return iter
Truancy
  • 23
  • 3
  • I think a simple while loop that multiplies digits together as long as the number is >10 should be simpler – Shrey Joshi Jun 01 '21 at 07:24
  • 1
    you have a typo in your first if block, you have to return the result of your persistence call: return persistence(result, iter) – AlbertFX91 Jun 01 '21 at 07:34

3 Answers3

1

I have read your question and find the problem you faced is interesting, your code is mostly right, that is, the if part without the recursive calls.

I have tweaked your code so that it takes only one argument uses a while loop, and uses math.prod() method so that you don't have to use a loop to get the products of a list.

while loop is basically if, except it checks the condition of result of the execution again after the execution, and if the result condition is still true it loops the execution until the condition is false.

To make the while loop recursive you only need to assign the result to the input:

chars = str(result)

So here is the code:

import math
def persistence(n):
    if n < 10: return 0
    else:
        chars = str(n)
        i = 0
        result = math.prod([int(y) for y in chars])
        while result > 10:
            i += 1
            result = math.prod([int(y) for y in chars])
            chars = str(result)
        return i
  • This got me a bit closer, unfortunately math.prod ran into an issue as soon as there was a 0 in the input. – Truancy Jun 01 '21 at 14:13
  • 1
    @Truancy My testings show the code works correctly, and there were no issues whatsoever if the inputs are valid. How are you able to make it generate wrong outputs? –  Jun 01 '21 at 14:41
  • If I call persistence with an input containing a 0 (270 for example), result returns 0. as I understand it, math.prod loops through the integers of chars and returns the product of the characters. 2*7*0 = 0 instead of 2*7 = 14 -> 1*4 = 4 – Truancy Jun 02 '21 at 12:31
  • And that is the correct behavior, because the definition specifies the result should be product of all digits, 0 included. –  Jun 02 '21 at 12:38
1

here inorder to solve any recursion question we do two things first we find the base case where the recursion will stop and rest we will call the recursion to do the things In this question you have defined the base case in else statement but not returned the recursive step the modified code is given below def persistence(n, iter=0): chars = str(n)

if n > 9:
    result = 1
    for y in chars:
        result = result * int(y)
    iter += 1
    return persistence(result, iter)

else:
    return iter

in short just apply return in persistence(result,iter) --> recursive function

Dharman
  • 30,962
  • 25
  • 85
  • 135
0

Maybe like so:

def persistance(x, mem = 0):
    x = str(x)
    if len(x) == 1:
        return (int(x), mem)
    else:
        tmp = '*'.join(list(x))
        return persistance(eval(tmp), mem + 1)

persistance(999)[1]
# 4
r.user.05apr
  • 5,356
  • 3
  • 22
  • 39