Project Euler 5 in Python - How can I optimize my solution?

后端 未结 20 896
醉梦人生
醉梦人生 2020-11-30 08:00

I\'ve recently been working on Project Euler problems in Python. I am fairly new to Python, and still somewhat new as a programmer.

In any case, I\'ve ran into a sp

相关标签:
20条回答
  • 2020-11-30 08:50

    Since your answer must be divisible by 20, you can start at 20 and increment by 20 instead of by two. In general, you can start at rangemax and increment by rangemax. This reduces the number of times div_check is called by an order of magnitude.

    0 讨论(0)
  • 2020-11-30 08:50

    This solution ran pretty quickly for me (imports numpy).

    t0 = time.time()
    import numpy
    
    ints = numpy.array(range(1,21))
    primes = [2,3,5,7,11,13,17,19] # under 20
    facts = []
    for p in primes:
        counter = 0
        nums = ints
        while any(nums % p == 0):
            nums = nums / float(p)
            counter += 1
        facts.append(counter)
    
    facts = numpy.array(facts)
    mults = primes**facts
    ans = 1
    for m in mults:
        ans = m * ans
    
    t1 =time.time()
    perf = t1 - t0
    print "Problem 5\nAnswer:",ans, "runtime:", perf, "seconds"
    
    """Problem 5
    Answer: 232792560 runtime: 0.00505399703979 seconds"""
    
    0 讨论(0)
  • 2020-11-30 08:51

    Two different types of solutions have been posted here. One type uses gcd calculations; the other uses prime factorization. I'll propose a third type, which is based on the prime factorization approach, but is likely to be much faster than prime factorization itself. It relies on a few simple observations about prime powers -- prime numbers raised to some integral exponent. In short, it turns out that the least common multiple of all numbers below some number n is equal to the product of all maximal prime powers below n.

    To prove this, we begin by thinking about the properties that x, the least common multiple of all numbers below n, must have, and expressing them in terms of prime powers.

    1. x must be a multiple of all prime powers below n. This is obvious; say n = 20. 2, 2 * 2, 2 * 2 * 2, and 2 * 2 * 2 * 2 are all below 20, so they all must divide x. Likewise, 3 and 3 * 3 are both below n and so both must divide x.

    2. If some number a is a multiple of the prime power p ** e, and p ** e is the maximal power of p below n, then a is also a multiple of all smaller prime powers of p. This is also quite obvious; if a == p * p * p, then a == (p * p) * p.

    3. By the unique factorization theorem, any number m can be expressed as a multiple of prime powers less than m. If m is less than n, then m can be expressed as a multiple of prime powers less than n.

    Taken together, the second two observations show that any number x that is a multiple of all maximal prime powers below n must be a common multiple of all numbers below n. By (2), if x is a multiple of all maximal prime powers below n, it is also a multiple of all prime powers below n. So by (3), it is also a multiple of all other numbers below n, since they can all be expressed as multiples of prime powers below n.

    Finally, given (1), we can prove that x is also the least common multiple of all numbers below n, because any number less than x could not be a multiple of all maximal prime powers below n, and so could not satisfy (1).

    The upshot of all this is that we don't need to factorize anything. We can just generate primes less than n!

    Given a nicely optimized sieve of eratosthenes, one can do that very quickly for n below one million. Then all you have to do is find the maximal prime power below n for each prime, and multiply them together.

    prime_powers = [get_max_prime_power(p, n) for p in sieve(n)]
    result = reduce(operator.mul, prime_powers)
    

    I'll leave writing get_max_prime_power as an exercise. A fast version, combined with the above, can generate the lcm of all numbers below 200000 in 3 seconds on my machine.

    The result is a 86871-digit number!

    0 讨论(0)
  • I think this the answer:

    primes = [11, 13, 17, 19]
    result = 2520
    
    for i in primes:
        result *= i
    
    print (result * 2)
    
    0 讨论(0)
  • 2020-11-30 08:54

    How I can reduce the complexity of this

    num = 1
    found = False
    while not found:
        count =0
        for i in range(1, 21):
            if num %i == 0:
                count+=1
        if count ==10:
            print(num)
            found = True
        num+=1
    
    0 讨论(0)
  • 2020-11-30 08:57

    List comprehensions are faster than for loops.

    Do something like this to check a number:

    def get_divs(n):
        divs = [x for x in range(1,20) if n % x == 0]
        return divs
    

    You can then check the length of the divs array to see if all the numbers are present.

    0 讨论(0)
提交回复
热议问题