Math geeks and computer nerds love to anthropomorphize numbers and assign emotions and personalities to them. Thus there is defined the concept of a "happy" number. A happy number is defined as an integer in which the following sequence ends with the number 1.

* Start with the number itself.
* Calculate the sum of the square of each individual digit.
* If the sum is equal to 1, then the number is happy. If the sum is not equal to 1, then repeat steps 1 and 2. A number is considered unhappy once the same number occurs multiple times in a sequence because this means there is a loop and it will never reach 1.

For example, the number 7 is a "happy" number:

7^(2) = 49 --> 4^(2) + 9^(2) = 97 --> 9^(2) + 7^(2) = 130 --> 1^(2) + 3^(2) + 0^(2) = 10 --> 1^(2) + 0^(2) = 1

Once the sequence reaches the number 1, it will stay there forever since 1^(2) = 1

On the other hand, the number 6 is not a happy number as the sequence that is generated is the following: 6, 36, 45, 41, 17, 50, 25, 29, 85, 89, 145, 42, 20, 4, 16, 37, 58, 89

Once the same number occurs twice in the sequence, the sequence is
guaranteed to go on infinitely, never hitting the number 1, since it repeat
this cycle.

Your task is to write a program which will print a list of all happy numbers between 1 and x (both inclusive), where:
```python
2 <= x <= 5000
```

___

Disclaimer: This Kata is an adaptation of a HW assignment I had for McGill University's COMP 208 (Computers in Engineering) class.

___

If you're up for a challenge, you may want to try a [performance version of this kata](https://www.codewars.com/kata/happy-numbers-performance-edition) by FArekkusu.

Difficulty: introductory

Starter code:

def happy_numbers(n):
	

Solutions:
def is_happy(n):
    seen = set()
    while n not in seen:
        seen.add(n)
        n = sum( int(d)**2 for d in str(n) )
    return n == 1


def happy_numbers(n):    
    return [x for x in range(1, n+1) if is_happy(x)]

# Code reuse: https://www.codewars.com/kata/reviews/5ac53889cd661be6ee0013ff/groups/5ac54c24cd661b3753001fba
# if you like this go the link and upvote StefanPochmanns's solution :)
def is_happy(n):
    while n > 4:
        n = sum(int(d)**2 for d in str(n))
    return n == 1


happy_numbers = lambda n: list(filter(is_happy, range(1, n+1)))

def happy_numbers(n):
    HappyNumbers = []
    for i in range(n+1):
        AlreadyGoneThrough = []
        a = i
        while a != 1 and a not in AlreadyGoneThrough:
            b = 0
            AlreadyGoneThrough.append(a)
            
            for digit in str(a):
                b = b + int(digit)**2
                
            a = b
            
        if a in AlreadyGoneThrough:
            pass
            
        elif a == 1:
            HappyNumbers.append(i)
    return HappyNumbers

def _sum_squares(num):
    ss = 0
    while num > 0:
        div, digit = num // 10, num % 10
        ss += digit * digit
        num = div
    return ss


def _is_happy_number(num):
    # Check if num is happy number.
    seens = set()
    while num > 1:  # stop when num == 1
        ss = _sum_squares(num)
        if ss in seens:
            return False

        seens.add(ss)
        num = ss
    return True


def happy_numbers(n):
    result = []
    for num in range(1, n + 1):
        # Check if a num is happy number.
        if _is_happy_number(num):
            result.append(num)
    return result


def happy_numbers(n):
    return [q for q in range(n+1) if isHappy(q)]
    
def isHappy(o, lister=[]):
    
    #Terminator
    if len(lister)>len(set(lister)): return False 
    
    #Test for Happiness
    summer=sum([int(p)**2 for p in str(o)])
    return True if summer==1 else isHappy(summer, lister+[summer])

from functools import lru_cache

visited = set()
@lru_cache(maxsize=None)
def happy(n):
    if n == 1 or n in visited:
        visited.clear()
        return n == 1
    visited.add(n)
    n = sum(int(digit)**2 for digit in str(n))
    return happy(n)

def happy_numbers(n):
    return [i for i in range(1, n+1) if happy(i)]

def happy_number(number):
    # Check 1: only happy numbers under 10 are (1,7)
    if number == 7 or number == 1: return True

    # Check 2: happy numbers if the sum of the square of each number == 1 (or 7)
    while number >= 10:
        number = sum(int(x)**2 for x in str(number))
    if number == 1 or number == 7: return True
    else: return False
print(happy_number(1112))

def happy_numbers(limit):
    return [number for number in range(1, limit+1) if happy_number(number)]

def _sum_squares(number):
    result = 0
    while number > 0:
        carry, digit = number // 10, number % 10
        result += digit * digit
        number = carry
    return result

def _is_happy_number(number):
    seens = set()
    while number > 1:
        # print('number:', number)
        sum_squares = _sum_squares(number)
        # print('sum_squares:', sum_squares)
        if sum_squares in seens:
            return False
        seens.add(sum_squares)
        # print('seens:', seens)
        number = sum_squares
    return True

def happy_numbers(n):
    result = []
    for number in range(1, n + 1):
        if _is_happy_number(number):
            result.append(number)
    return result

def sum_square(num):
    num2 = str(num)
    sum_sqr = 0
    for val in num2:
        sum_sqr += int(val) ** 2
    return sum_sqr


def happy_numbers(n):
    happy = []
    for val in range(1,n+1):
        val_list = []
        wag = 100
        val2 =  val
        for iii in range(wag):
            sum_sqr = sum_square(val2)
            if sum_sqr == 1:
                happy.append(val)  # happy
                break
            elif sum_sqr in val_list: # infinate loop
                break
            else:
                val_list.append(sum_sqr)
                val2 = sum_sqr

    return happy


def happy_numbers(n):
    return [k for k in range(1,n+1) if is_happy(k)]

def is_happy(n):
    seen = {n}
    while n != 1:
        n = sum(int(d)**2 for d in str(n))
        if n in seen: return False
        seen.add(n)
    return True