首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Euler # 21项目友好数字Python

Euler # 21项目友好数字Python
EN

Code Review用户
提问于 2019-07-19 07:34:23
回答 1查看 243关注 0票数 1

d(n)定义为n的适当除数之和(小于n的数,它均匀地划分为n)。如果d(a) = bd(b) = a,其中a ≠ b,那么ab是友好的对,ab中的每一个都被称为友好数。

例如,220的适当除数是1、2、4、5、10、11、20、22、44、55和110;因此d(220) = 284。284的适当除数为1、2、4、71和142;so _ d(284) = 220。

评估所有友好人数少于10000的总和。下面是我在Python中的实现。我需要你对如何改进这个问题的反馈。

注:我是编程初学者。

代码语言:javascript
复制
from time import time


def get_divisors(n):
    """Yields divisors of n."""
    divisor = 2
    while divisor * divisor <= n:
        if n % divisor == 0 and n // divisor != divisor:
            yield divisor
            if n // divisor != divisor:
                yield n // divisor
        divisor += 1
    yield 1


def get_sum_amicable(n, divs={2:1}):
    """Yields amicables below n."""
    for number1 in range(n):
        for number2 in range(number1):
            try:
                if divs[number2] == number1 and divs[number1] == number2:
                    yield number1
                    yield number2
            except KeyError:
                divs[number1] = sum(get_divisors(number1))
                divs[number2] = sum(get_divisors(number2))
                if divs[number2] == number1 and divs[number1] == number2:
                    yield number1
                    yield number2


if __name__ == '__main__':
    start = time()
    print(sum(get_sum_amicable(10000)))
    print(f'Time: {time() - start} seconds.')
EN

回答 1

Code Review用户

回答已采纳

发布于 2019-07-19 08:20:06

可读性/可维护性

代码语言:javascript
复制
def get_sum_amicable(n, divs={2:1}):
    """Yields amicables below n."""
    for number1 in range(n):
        for number2 in range(number1):
            try:
                if divs[number2] == number1 and divs[number1] == number2:
                    yield number1
                    yield number2
            except KeyError:
                divs[number1] = sum(get_divisors(number1))
                divs[number2] = sum(get_divisors(number2))
                if divs[number2] == number1 and divs[number1] == number2:
                    yield number1
                    yield number2

这太可怕了。它违反了“不要重复自己”的规则;它期望异常作为非例外流的一部分;它依赖于一个模糊的语言特性/错误特性。

您所需要做的就是求和数x in range(n) (或者,也许更好的是range(2, n),以避免01周围的复杂情况),对于它,d(x) < n and d(d(x)) == x。(考虑到问题的措辞方式,您可能会假设不会有围绕n的友好对,因此测试的前半部分可能是不必要的)。这是一条单线。

如果要缓存d,则可以使用functools.lru_cache而不是使用默认值。但是..。

性能

每当您对从1n的每个数字进行可分性检查时,都应该考虑使用筛子。要么构建一个由每个数的一个素因子组成的数组,然后以此为基础工作,要么(在适当的情况下)将计算嵌入到筛子处理中。

很容易调整Eratosthenes的筛子,使用内联方法高效地生成一个d数组。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/224461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档