首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >项目Euler #5 (LCM of [1,2,…]),20])

项目Euler #5 (LCM of [1,2,…]),20])
EN

Code Review用户
提问于 2013-11-16 22:43:49
回答 2查看 1.3K关注 0票数 4

我已经实现了项目欧拉问题5的解决方案:

2520是最小的数,可以除以从1到10的每一个数,没有任何余数。什么是最小的正数,可以被从1到20的所有数字整除?

我的解决方案使用Python2.7,由我创建的一个模块组成,该模块查找数字的主要因素-- factorization模块。它包含在同名Python源文件中实现的函数factors()primegen()。在项目的顶层,我定义了一个函数smallest_multiple(),它使用factors(),并在同一个文件中定义一个main()函数来驱动它。

factorization模块

primegen.py:

代码语言:javascript
运行
复制
import itertools

def primegen(upper):
    """Return generator yielding all primes less than upper 
    >>> list(primegen(10))
    [2, 3, 5, 7]
    >>> list(primegen(30))
    [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
    """

    # http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
    marked = [False] * (upper - 2)

    # using generator here lets us lazily evaluate whether
    # a number has been marked
    def next_p():
        for i,v in enumerate(marked):
            if not v:
                yield i

    def generate_primes():
        for p_idx in next_p():
            p = p_idx + 2
            cursor = p
            while True:
                cursor = cursor + p
                try:
                    marked[cursor-2] = True
                except IndexError:
                    break
            yield p

    return generate_primes()

factors.py:

代码语言:javascript
运行
复制
from factorization.primegen import primegen

def factors(n):
    """generator function yielding the prime factors of n
    Heavily derived from http://en.wikipedia.org/wiki/Trial_division
    >>> list(factors(14))
    [2, 7]
    >>> list(factors(13195))
    [5, 7, 13, 29]
    >>> list(factors(8))
    [2, 2, 2]

    """

    for p in primegen(int(n**0.5) + 1):
        # sqrt(n) < p => n = q * (p^k), where k is 0 or 1, and q is product of each element of factors
        if p*p > n:
            break
        # append factor for each time it appears
        while not n%p:
            yield p
            n = n / p
    if n > 1:
        yield n

顶级

e5.py:

代码语言:javascript
运行
复制
#!/usr/bin/env python

from factorization.factors import factors

def smallest_multiple(n):
    """Returns smallest multiple evenly divisble by each 1..n in N

    >>> smallest_multiple(10)
    2520

    """

    # for each number <= n, find its prime factors p1^k1, p2^k2, ...
    #   store as prime => exponent
    #       replace existing stored exponents only if the replacement is greater
    # for each prime=>exponent
    #   result = result * prime^exponent
    factor_exp_map = {}
    for i in xrange(n,0,-1):
        facs = list(factors(i))
        for factor in facs:
            fact_count = facs.count(factor)
            cur_fact_count = factor_exp_map.get(factor,0)
            if (fact_count > cur_fact_count):
                factor_exp_map[factor] = fact_count
    result = 1
    for factor, exponent in factor_exp_map.iteritems():
        result = result * factor**exponent
    return result

def main():
    print('result = {0}'.format(smallest_multiple(20)))

if __name__ == '__main__':
    main()

整个项目可以找到论吉乌布。它的唯一增加是一个崇高文本2项目和一些脚本,以便在编辑器中运行doctest。

我确实对这段代码有一些特别的关注。我发现smallest_multiple()是奇怪的和笨重的-特别是迭代每个因素元素并要求它的计数。似乎应该有一些更优雅的方法来汇总这些因素及其指数。我想知道我的docstring和doctest是否合理,以及我的模块组织是否一致。我还想知道我是否在滥用生成器,特别是在doctest中,在每个生成器上调用list()以获得结果,以及在primegen()中调用嵌套生成器函数。

一般来说,我还想得到关于这个代码是怎样的Pythonic的反馈。我一直在努力记住PEP 8,但是我匆忙忽略的任何偏差都是很好的了解。在输入验证和健壮性方面,我也做得不多,所以我希望能就这样做的惯用方式提供一般性建议。

EN

回答 2

Code Review用户

发布于 2013-11-19 18:41:33

这是相当不错的Python。我的意见是:

  • 可能设计得有点过火了。对于这样一个小问题,简单比可伸缩性更好。例如,你可以不用埃拉托斯提尼的筛子。
  • 将重复的素因子聚集成指数很可能被认为是factors()函数的责任。
  • 如果您使用更多的功能(而不是过程)样式,那么代码会更紧凑;如果使用更多的数学词汇表(例如“产品”和“最不常见的倍数”),代码会更清晰。

前一次审查说明了这些原则。

票数 1
EN

Code Review用户

发布于 2013-11-20 21:32:16

我的眼睛里有几样东西:

  1. 每次对factors的调用都会从头开始运行Eratosthenes的筛子。
  2. 这..。cursor =p而True: cursor = cursor +p try:光标-2= True除了IndexError:...is -这是对xrange中的for循环相当笨重的替代(2*p-2,len(标记),p):标记游标= True
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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