这是任务:
问题23
一个完美数是一个数字,它的适当除数之和等于该数字。例如,适当除数28的总和就是1 + 2 + 4 + 7 + 14 = 28,这意味着28是一个完美的数。
如果数字n的适当除数之和小于n,则称n为不足;如果数字n的适当除数超过n,则称其为丰富。
由于12是最小的丰富数,所以1 + 2 + 3 + 4 + 6 = 16,可以写成两个丰富的数之和的最小数是24。通过数学分析,可以看出所有大于28123的整数可以写为两个丰富数字的总和。但是,即使知道无法表示为两个丰富数字之和的最大数字小于该上限,也无法通过分析进一步降低该上限。
找到所有不能写为两个丰富数字之和的正整数之和。
这是我的代码:
import time
import math
start = time.time()
abundant_num_list = []
def checkAbundant():
for n in range(1, 28123):
factor_sum = 0
other_pair_factor = 0
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
if math.floor(math.sqrt(n)) == math.sqrt(n):
other_pair_factor = 0
else:
other_pair_factor = n // i
factor_sum += (i + other_pair_factor + 1)
if n < factor_sum :
abundant_num_list.append(n)
def NonAbundantSums():
abundant_sum_list = []
all_num_list = []
non_abun_list = []
non_abun_sum = 0
for i in range(len(abundant_num_list)):
for j in range(i, len(abundant_num_list)):
if abundant_num_list[i] + abundant_num_list[j] <= 28123:
abundant_sum_list.append(abundant_num_list[i] + abundant_num_list[j])
for i in range(1, 28124):
all_num_list.append(i)
non_abun_list = [int(a) for a in (set(all_num_list) - set(abundant_sum_list))]
for i in range(len(non_abun_list)):
non_abun_sum += non_abun_list[i]
print(non_abun_sum)
checkAbundant()
NonAbundantSums()
end = time.time() - start
print("Done in", end, "seconds")
如果它看起来效率低下,我知道,我是编码新手。 Python是我的第一门编程语言。我注意到我的non_abun_list有一个怪异的问题,当检索set(all_num_list)和set(abundant_sum_list)的差时,rich_sum_list的第一和第二个索引是2和30,所以在我看来,non_abun_list应当像
[1、2、3、4 ...,22、23、25、26、27、28、29、31、32]
相反,我得到了这个
[1、2、3、4 ...,22、23、8209、25、26、27、28、29、8219、31、32]
,我不知道该如何获得此列表。 有人可以向我解释我的代码有什么问题吗? 我的结果是〜25秒内4352518 答案是4179871
答案 0 :(得分:0)
这不是答案
(由于代表的要求,OP无法参与聊天)
您应该考虑自己的编码风格。如果您编写简洁的函数来执行任务,并让这些函数返回一个或多个值,那么您可以轻松地测试这些函数以查看它们是否有效。这样可以更轻松地确定什么在起作用。
例如,当检查丰度时,您必须做两件事:找到一个数字的除数,然后将它们的和与该数字进行比较。
def divisors(n):
'''return divisors of n'''
d = [1]
for i in range(2, int(pow(n,.5))+1):
if (n % i) == 0:
other = n // i
if other == i:
pair = [i]
else:
pair = [i,other]
d.extend(pair)
return d
def check(n):
'''return True if abundant'''
return sum(divisors(n)) > n
现在,如果您开始遇到问题,则可以轻松针对已知输入和输出测试这两个功能。知道它们有效后,您就不必将其视为错误的来源。
用法:
abundant_numbers = []
for n in range(12,28124):
if check(n):
abundant_numbers.append(n)
测试几个数字:
>>> divisors(16)
[1, 2, 8, 4]
>>> divisors(1056)
[1, 2, 528, 3, 352, 4, 264, 6, 176, 8, 132, 11, 96, 12, 88, 16, 66, 22, 48, 24, 44, 32, 33]
>>> check(16)
False
>>> check(1056)
True
>>>
是的,看起来不错:)。
答案 1 :(得分:0)
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
if math.floor(math.sqrt(n)) == math.sqrt(n) == i:
other_pair_factor = 0
else:
other_pair_factor = n // i
factor_sum += (i + other_pair_factor)
factor_sum += 1
对于checkAbundant()的这一特定部分,我应该在第3行添加“ == i”,因为我只希望重复两次的因子只对平方数计数一次
例如,我要称呼为36的配对因子为1 x 36、2 x 18、3、12、4 x 9、6 x 6。
为了提高效率,我只找到因子对的前一半,另一半通过n // i获得。因此,为了拥有一定数量的适当因子的总和,我不能有重复的因子。
我没有添加“ == i”,所以对于任何平方丰富的数字,求和总因数时都不会考虑它们的另一半。
我在checkAbundant()中修复的另一个错误在第8行中,其中factor_sum + =(i + other_pair_factor +1)
这导致每个循环,factor_sum将有一个额外的1,这将破坏结果。为了解决这个问题,我在for循环后添加了1
总的来说,我会说这是一个新秀错误。 >。<< / p>