首先打印n Happy Numbers - Python

时间:2018-01-25 12:57:38

标签: python function recursion

我在python中写了一段代码来检查一个给定的数字是否满意,即取数字并加上它们的平方和是1,这是一个快乐的数字,或者以一个永无止境的循环结束它定义了一个不愉快的数字。 在那之后,我想列出前n个快乐号码。我得到了快乐数字的检查,虽然很邋,,但我似乎无法弄清楚上市部分。

def adder(num):
    total=0
    if len(str(num))>1: #check if given number is double digit or not
        tens = int(str(num)[0]) # splitting the digits 
        ones = int(str(num)[1])
        total = (tens**2)+(ones**2) # summing up the squares 
        #print (total)
        return total
    else: # if the given number  is a single digit
        total = (num**2)
        #print (total)
        return total

#adder(9)

def happynumber(num, counter):
    N = adder (num) # storing the sum in a variable 


    #print ("value of n is {}".format(N)) 
    if N == 1: #checks if the sum is 1
       # print ("In just {} tries we found that {} is a happy number.".format(counter, number))
        print (number)



    else: # if the sum isn't 1, racalls the happynumber function 
        counter += 1 # keeps track of number of tries so that we don't end up in an infinite loop
        if counter < 11: # setting the limit for number of tries
            #print (counter) 
            happynumber (N, counter)
        else:
            #print ("it took us {} tries and found that the number {} is not a happy number".format(counter, number))
            return False       

counter = 0


for i in range(0,100): # listing all the happy numbers between 0 and 100
    number = i
    happynumber (number, counter)

此外,如果你们会审查我的写作风格并给出一些指示,我希望如此。

问题是,我无法列出前n个数字但是我尝试的方式。

我尝试在循环中使用计数器,但无济于事。

4 个答案:

答案 0 :(得分:1)

首先,你不应该传递counter变量,因为它是一个全局变量。我也可能只是为了确保没有问题而在你的方法之上声明它。

您的下一个问题是您从未重置counter变量。因此,第一次程序遇到一个在10次尝试后不满意的数字,它会继续为第一次尝试后不满意的每个数字返回false。尝试在counter = 0区块中的return False行之前添加if counter < 11/else

答案 1 :(得分:1)

如果你的主要问题是你想在列表中包含所有喜欢的数字,你可以通过在递归循环之外定义一个列表来轻松解决这个问题。

def happynumber(num, counter):
    N = adder(num)  

    if N == 1: 
        happyhappy.append(number)      #new happy number into list
    else: 
        ...continue with your code       

#-------main script-------------
happyhappy = []                        #create a list to store your happy numbers
counter = 0
for i in range(100): 
    number = i
    happynumber(number, counter)

print(happyhappy)                      #and retrieve the list

说过adder()功能效率低下。它最多只计算两位数。更糟糕的是,它必须从头开始对每个数字执行平方操作,这非常耗时。

更好的方法是预先计算方块并将它们存储在字典中:

square_dic = {str(i): i ** 2 for i in range(10)}  #create a dictionary of squares
def adder(num):                           
    s = str(num)                                  #make the number into an iterable string
    x = [square_dic[i] for i in s]                #look up the square of each digit
    return sum(x)                                 #and calculate the sum of squares

感谢Python中的列表推导,我们可以使它更加快捷

square_dic = {str(i): i ** 2 for i in range(10)}
def adder(num):                                   #does exactly, what the other function did
    return sum(square_dic[i] for i in str(num))

答案 2 :(得分:1)

以下是对当前代码进行非常小的更改的示例。我为happynumber函数添加了另一个输入,即您要存储快乐数字的列表。

我确信这不是最有效的方式,但它显示了如何更新代码。

代码:

def happynumber(num, counter, the_list):
    N = adder(num); 
    print ("value of n is {}".format(N));
    if counter == 0:  #THIS IS ADDED
        the_list.append(num); #THIS IS ADDED
    if N == 1: 
        print ("In just {} tries we found that {} is a happy number.".format(counter, number))
        print (num);
    else: 
        counter += 1
        if counter < 11:
            print (counter) 
            happynumber(N, counter, the_list)
        else:
            print ("it took us {} tries and found that the number {} is not a happy number".format(counter, number))
            the_list.pop(); #THIS IS ADDED
            return False       

counter = 0;

happynumber_list = []; #THIS IS ADDED
for i in range(0,100): 
    number = i
    happynumber (number, counter, happynumber_list)

在第一次尝试中,号码将被存储到列表中......但如果找到的号码不是一个满意的号码,那么该号码将从列表中pop

结果如下:

[1, 7, 10, 13, 19, 23, 28, 31, 32, 44, 49, 59, 68, 70, 79, 82, 86, 91, 94, 95, 97]

这可以吗?

答案 3 :(得分:0)

您可以使用memoization来不必使用计数器。我还会使用生成器(yield),因此只会生成您要求的结果数。然后你不必指定一个范围(0,100),但可以指定你想要前25个满意的数字(或任何需要的数字)。

以下是这样的:

import itertools

def sum_digit_squares(num):
    return sum(int(i)*int(i) for i in str(num))

def happynumbers():
    memo = { 1: True }
    for i in itertools.count(): # forever (as long as getting from this iterator)
        result = None # Will become either True (happy) or False (not happy)
        visited = set()
        j = i
        while result is None:
            if j in memo: # Did we make the calculation for this one before?
                result = memo[j] 
            elif j in visited:
                result = False # endless loop detected
            else:
                visited.add(j)
                j = sum_digit_squares(j)
        for j in visited:
            memo[j] = result
        if result:
            yield i

print (list(itertools.islice(happynumbers(), 0, 25))) # Produce first 25 happy numbers