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
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.
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"""
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.
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
.
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
.
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!
I think this the answer:
primes = [11, 13, 17, 19]
result = 2520
for i in primes:
result *= i
print (result * 2)
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
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.