[Tutor] To find the least number divisible by all numbers from 1-20
#PATHANGI JANARDHANAN JATINSHRAVAN#
JATINSHR001 at e.ntu.edu.sg
Wed Aug 14 04:49:47 CEST 2013
________________________________________
From: Tim Peters [tim.peters at gmail.com]
Sent: Wednesday, August 14, 2013 02:35 AM
To: #PATHANGI JANARDHANAN JATINSHRAVAN#
Cc: tutor at python.org; N_Gopalakrishnan at Dell.com; pathangi_janardhanan at dell.com
Subject: Re: [Tutor] To find the least number divisible by all numbers from 1-20
[#PATHANGI JANARDHANAN JATINSHRAVAN#]
> ///
> I am solving problem number 5 in project euler. I think my solution seems
> logically correct but it is not giving an answer as it is taking too long to
> execute.
It does take a long time, but it does return the correct answer - eventually ;-)
> So can someone suggest an alternative solution? Here is my source
> code:
>
> import sys
> def check(num):
> lis=[20,19,18,17,16,14,13,11] #because a no. divisible by 20 is divisible
> by 2,4,5 and so on for the values omitted
> for i in lis:
> if num%i==0:
> continue
> else:
> return False
> break
>
> return True
Simpler:
def check(num):
return all(num % i == 0 for i in [20,19,18,17,16,14,13,11])
> def main():
> num=2520 # Because we can start from the no. divisible by 1-10
> while not check(num):
> print(num)
> num+=2 # Because num has to be even
You can speed this up by a factor of about 1000 via incrementing by
2520 instead of by 2. Because the correct answer has to be divisible
by all of 1 thru 10, it has to be divisible by 2520 too, right?
Therefore the correct answer must be a multiple of 2520.
Incrementing by 2520 drastically speeds up the execution time. Thanks, I didn't think of that. And I'm still trying to comprehend the LCM and GCD methods. I'm pretty new to programming and python.
> print(num)
Peter is on "the best" track via exploiting this fact:
lcm(a, b) = a * b // gcd(a, b)
The problems he hit with recursion can be avoided by using an
iterative gcd function instead. Like so:
def gcd(a, b):
while b:
a, b = b, a % b
return a
def lcm_list(ns):
sofar = 1
for n in ns:
sofar = sofar * n // gcd(sofar, n)
return sofar
Then:
>>> print lcm_list(range(1, 21)) # your case
232792560
That takes a small fraction of a second. So does this:
>>> print lcm_list(range(1, 101))
69720375229712477164533808935312303556800
Even this takes a fraction of a second!:
>>> print lcm_list(range(1, 1001))
7128865274665093053166384155714272920668358861885893040452001991154324087581111499476444151913871586911717817019575256512980264067621009251465871004305131072686268143200196609974862745937188343705015434452523739745298963145674982128236956232823794011068809262317708861979540791247754558049326475737829923352751796735248042463638051137034331214781746850878453485678021888075373249921995672056932029099390891687487672697950931603520000
Amazing, eh? :-)
More information about the Tutor
mailing list