0
class Solution:
    def isHappy(self, n):
        list_n, l, ls, num = [n,], 0, 0, 0
        while num != 1:
            if l != ls:
                return False
            num = sum([int(i)**2 for i in list(str(n))])
            list_n.append(num)
            l, ls = len(list_n), len(set(list_n))
        return True

Input: 7

Output: False

Expected: True

It's from Happy Number | LeetCode OJ

Write an algorithm to determine if a number is "happy".

A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.

7
  • why is it a class? Also sum(int(i)**2 for i in list(str(n))) would be better, you are building a list for no reason Commented May 14, 2015 at 21:28
  • 1
    The moment list_n has repeated values, it will return False Commented May 14, 2015 at 21:33
  • It's built as a class because I copied it from OJ. Commented May 14, 2015 at 21:37
  • Thanks for your suggestion on my list comprehension. Commented May 14, 2015 at 21:37
  • I know that my list maybe duplicated to see such a sequence. However, for happy number, would the list be duplicated before it contains several one? Once num equals one, it supposes to quit the while loop. 😢bi Commented May 14, 2015 at 21:45

3 Answers 3

1

To answer the question: Your code fails because you're confusing num and n. In particular, you compute num always from n, and neither ever changes. Just get rid of one of them, that will also be less confusing. You really should learn to debug, btw... printing num or n inside the loop would have made it clear what's happening.

Using a set would btw be easier and faster, try that as well. Here's one way:

def isHappy(n):
    stop = {1}
    while n not in stop:
        stop.add(n)
        n = sum(int(d)**2 for d in str(n))
    return n == 1

And here's one that only uses two single ints. Can you see how it works?

def isHappy(n):
    s = lambda n: sum(int(d)**2 for d in str(n))
    m = s(n)
    while m != n:
        n, m = s(n), s(s(m))
    return n == 1
Sign up to request clarification or add additional context in comments.

4 Comments

I don't see where this answers the question. The question asks what's wrong with the given code. The question does not ask for a solution to the happy-number problem.
@RobKennedy I answered that now. Is it ok now?
Thank you~your solution is as well very enlightening.
God I love the lambda solution! I am a newbie in programming and really appreciate such help!
1

The reason is as below:

n has to be reset to newest result after each sum operation. So just add this line before return True :

n=num

And for your reference, here is the working code:

def isHappy(n):
list_n, l, ls, num = [n,], 0, 0, 0
while num != 1:
    if l != ls:
        return False
    num = sum([int(i)**2 for i in list(str(n))])
    list_n.append(num)
    l, ls = len(list_n), len(set(list_n))
    n=num # reset n after each sum calculation
return True

Comments

0

You can keep looping while sm which is the sum of the squares of the digits of the current n or until sm is repeated. Returning sm == 1 to test if the number is happy:

def isHappy( n):
    # set initial sum of squares
    sm = sum(int(i) * int(i) for i in str(n))
    seen = set()
    # while we have not hit 1 or we get a repeated `sm`
    while sm != 1 and sm not in seen:
        # add sm to our set
        seen.add(sm)
        # update sm
        sm = sum(int(i) * int(i) for i in str(sm))
    # we will get here either when sm is 1 or we had a repeated sm
    return sm == 1

Output:

In [2]: for x in range(100+1):
   ...:     if isHappy(x):
   ...:           print(x)
   ...:         
1
7
10
13
19
23
28
31
32
44
49
68
70
79
82
86
91
94
97
100

As per the wiki page description in your question If n is not happy, then its sequence does not go to 1. Instead, it ends in the cycle so if we see repeated values we know the number is not happy. I don't see anywhere in your code that you are checking that condition.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.