Project Euler 5

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 positive number that is evenly divisible by all of the numbers from 1 to 20? – PROJECT EULER #5

Pretty straight forward today. Basically, we’re looking for the least common multiple (lcm) of all of the numbers from 1 to 20. So, we’ll start with that. Here’s a way to define lcm, directly from the wikipedia article:

lcm(a,b)=\frac{ |ab| }{gcd(a,b)}

This translates pretty directly:

; find the least common multiple of two numbers
; source: http://en.wikipedia.org/wiki/Least_common_multiple
(define (lcm a b)
  (/ (abs (* a b)) (gcd a b)))

Luckily, lcm is commutative, so (lcm (lcm a b) c) is the same as (lcm a (lcm b c)), etc.

However, as you may have noticed, we need another function: gcd (the greatest common divisor). Euclid’s algorithm is both straight forward and nicely expressed in a recursive fashion:

gcd(a,b) = \begin{cases} a &\mbox{if } b=0 \\ gcd(b,mod(a,b)) & \mbox{otherwise} \end{cases}

And now in code:

; find the greatest common divisor of two numbers
; source: http://en.wikipedia.org/wiki/Greatest_common_divisor
(define (gcd a b)
  (if (= b 0)
      a
      (gcd b (remainder a b))))

With that, it’s nice and easy to calculate the least common multiple of 1 through any number n. Just use the same for/fold macro I talked about yesterday (albeit without the *):

; calculate the least common multiple of a range
(define (least-common-multiple-up-to n)
  (for/fold ([res 1])
            ([i (in-range 1 (+ n 1))])
    (lcm res i)))

So we start with the result res at 1 then repeatedly take the lcm of the current result and the new number. Check it on the small example given:

> (time (least-common-multiple-up-to 10))
cpu time: 0 real time: 0 gc time: 0
2520

Good to go. Extend it for the full example:

> (time (least-common-multiple-up-to 20))
cpu time: 0 real time: 0 gc time: 0
232792560

And we’re good to go. You can’t really beat 0 ms.

As always, you can download my code for this or any Project Euler problem I’ve uploaded here.