I love python, there are many ways to solve problems, I specially like when seeing short-code or reduced solutions using advanced functions of the language but because I’m learning to code, I prefeer solving problems by dividing them into smaller parts, this is the longest way but the easier and educational one.

In this post I’m showing you multiple ways we can use to solve the same problem in python, in this case a multiplicative persistence problem.

Multiply all the numbers in an integer number

Supose we have the number ‘1234’ as an integer like this:

#/usr/bin/python
#miguel.ortiz

myNumber=1234

And we want to multiply each number of this integer like this: 1x2x3x4, we could go this way:

#/usr/bin/python
#miguel.ortiz

# our integer
myNumber=1234
# the variable for the loop start
product=1

# to iterate over the integer we must convert it to a string, integers aren't iterable.
for i in str(myNumber) :
    #because "i" is a string, we must convert it to a number with int()
    product *= int(i)

    #print the result
    print product

And this is the output:

mortiz@alberta:~/Documents/projects/python$ python multiplicative_persistence.py  
1
2
6
24

Multiply all the numbers in a python list

Now imagine we don’t have an integer, but a list of numbers and we want to multiply them all, that it’s quite similar to the previous snippet but simpler:

#/usr/bin/python
#miguel.ortiz

# our integer
myNumber=[1,2,3,4]
# the variable for the loop start 
product= 1

# we do not need to convert anything, you can iterate over lists 
for i in myNumber :
    #we do not need to convert anything, "i" it's an integer
    product *= i

    #print the result
    print product

And of course our output is correct again:

mortiz@alberta:~/Documents/projects/python$ python multiplicative_persistence.py  
1
2
6
24

The multiplicative persistent problem

Now let’s deal with the real thing. In this case we want the number of times we must multiply each number of an integer until we get one digit integer, the so called persistence:

  • 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.

The solution for this problem would be:

  • If the integer has only one digit then the result is 0
  • If the integer has more than one digit then:
    • Split the numbers of the integer, then multiply
    • Take the result, if it has more than one digit, multiply again
    • Repeat previous step until reach one digit
    • When reach one digit stop and tell how many times we repeated the process

As I’ve said before, dividing the problem in small parts make it easy to solve it:

  • First we create a function to process an integer, split it, then multiply it’s digits one at a time, that is the «multip» function which is exactly as the first script under (multiply all numbers in an integer number)
  • After that, we create a conditional or «control structure» to evaluate if the processed number has more than 1 digit, if that’s true then a loop will iterate over and over until one digit is reached.
  • Finally, when the processed integer is one digit the loop stops and print the number of times (counter) that was executed.
#!/usr/bin/python
#miguel.ortiz
digit=999
counter=1
product=1

for i in digit :
    product *= i
    print product

def multip(numbers) :
    product= 1
    for i in str(numbers) :
        product *= int(i)
    return product

if len(str(digit)) > 1 :
    while True :
        product=multip(digit)
        if len(str(product)) > 1:
            counter += 1
            digit = product
        else :
            return counter
else :
    return 0

That’s too much for a simple task, let’s take a look of a smaller version of this script. This one is just one function and process everything inside the same loop.

#/usr/bin/python
# anonymus
n=999
def persistence(n):
    if str(n) == 1:
        return 0
    count = 0
    while len(str(n)) > 1:
        total = 1
        for i in str(n):
            total *= int(i)
        n = total
        count += 1
    return count
persistence(n)

Now the smallest solutions with advanced python functions.

Using Reduce + mul

#/usr/bin/python
#anonymus

from operator import mul
n=999

def persistence(n, res=0):
    return persistence(reduce(mul, map(int, str(n))), res+1) if n > 9 else

persistence(n)

Using Reduce + Lambda

#/usr/bin/python
#anonymus

n=999

def persistence(n):
    nums = [int(x) for x in str(n)]
    sist = 0
    while len(nums) > 1:
        newNum = reduce(lambda x, y: x * y, nums)
        nums = [int(x) for x in str(newNum)]
        sist = sist + 1
    return sist

persistence(n)

Using reduce + mul in one line solution

#/usrb/bin/python
#anonymus
n=999

from operator import mul
def persistence(n):
    return 0 if n<10 else persistence(reduce(mul,[int(i) for i in str(n)],1))+1

persistence(n)

All of this clearly shows how a problem may be approached in different ways, the most important is not only how to use an specific function of the language but uderstanding problems or finding a way to solve them, if we can do that, then we can start thinking about optimizing performance on a particular snippet of code.