Project Euler 5: Find the Lowest Common Multiple
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?
This means that you have to find the lowest common multiple of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 and 20. Here is a Perl script that does that very thing through brute force:
1 2 3 4 5 6 7 8 9 10 | for ( my $n = 20; 1; $n++ ) { # do forever for ( 1..20 ) { # for every integer from 1 to 20 if ( $n % $_ ) { # if $n is not divisible by the integer.. last; # ..end the for-loop } if ( $_ == 20 ) { # if $n has been divisible by every number up to 20.. die $n; # ..print the result and terminate the script } } } |
However, this script will probably take 20 minutes or so to interpret. In order to optimize it, we could first remove some of the numbers that are divided with. 1 is unnecessary since all natural numbers are divisible by 1. We don’t need 2, either, since all numbers divisible by multiples of 2 (such as 4 or 18) are divisible by 2, too. This way, we can deduce away all of the numbers except: 11, 12, 13, 14, 15, 16, 17, 18, 19 and 20.
This isn’t the end of the optimization: Why are we incrementing only by 1? If we increment $n by 20 every loop, we will still get all values that are divisible by 20. This way, we can make the code a lot faster — after applying this step, I found the answers in 16 seconds instead of 700 seconds. This is the final script, with lines 1, 2 and 6 changed.
1 2 3 4 5 6 7 8 9 10 | for ( my $n = 20; 1; $n += 20 ) { # do forever, incrementing by 20 for ( 11,12,13,14,15,16,17,18,19 ) { # for the relevant integers if ( $n % $_ ) { # if $n is not divisible by the integer.. last; # ..end the for-loop } if ( $_ == 19 ) { # if $n has been divisible by every number up to 19.. die $n; # ..print the result and terminate the script } } } |

Good job, but your optimisation doesn’t have to end there, you can increase the increment as you find extra factors. For example, you start with an increment of 20. When you find the first number that’s also a factor of 19 (380), the solution has to be a multiple of it, so you can increase the increment to 380. The first number with 20, 19 and 18 as a factor is 3420, and 20,19,18,17 is 58140! This way you can leap past thousands of numbers that can’t be the answer without testing them.
Comment by James — August 31, 2007 @ 4:30 pm
Wow, didn’t think of that, James. Thank you :)
Comment by Tim — September 15, 2007 @ 8:17 am
oh this is confusing :-(
Comment by Anonymous — November 2, 2007 @ 5:02 pm
You can also increase efficiency by checking divisibility backwards - start with 19 and work down to 11. A C based language would look something like this:
for(int i = 19; i > 10; i–)
if(n%i != 0)
break;
Comment by Anonymous — August 4, 2008 @ 12:29 pm