CodeEval Happy Numbers

Check if a number is happy. Meaning that, adding up the squares of its digits we get one, or a number that, following the same recursice procedure, leads to one. A better description is on CodeEval. Now I see that I have already solved this problem a few years ago using C++ as implementation language. This time I used Python, and I have to say that the code looks more readable to me.

The core of the procedure to check if a number is happy requires to add on all its squared up digits. Thinking in a pythonic way, I have seen it as summing all the elements resulting from a custom iteration. I focused on the iterative part of this sub-problem, creating a generator that does the job:
def squared_ciphers(number):
    while number:
        number, cipher = divmod(number, 10)  # 1
        yield cipher ** 2  # 2
1. The handy built-in function divmod() returns the quotient and the remainder of the integer division by its passed parameters. I use it to get the rightmost digit in cipher removing it from number.
2. Each digit is squared and returned.

Now I am ready for the main part of the script. I am about to loop indefinitely until I see the number is happy or sad. Luckly we know that this loop is not infinite. See wikipedia for details.
def solution(line):
    candidate = int(line)
    explored = set()
    while candidate != 1:  # 1
        if candidate in explored:  # 2
            return 0
        candidate = sum(squared_ciphers(candidate))  # 3
    return 1
1. If I get a 1, the originating number is happy. I can stop looping.
2. I store all the generate numbers in a set, so that I can easily check if I have already seen the current element. If so, I know I am entering a deadly loop, and so I can safely state the checked number is not happy.
3. I need to generate a new number from the current one. I call the generator to get all its squared ciphers, and I send the results to the sum() built-in function, so to get it.

Happy or not, this script nails it. You can get the full Python3 source from GitHub.

No comments:

Post a Comment