## Project Euler in F# – Problem 53

Some of the problems proposed by Project Euler actually present the solution together with the description of the problem itself.

This is the case with Problem 53:

There are exactly ten ways of selecting three from five, 12345:

123, 124, 125, 134, 135, 145, 234, 235, 245, and 345

In combinatorics, we use the notation, ^(5)C_(3) = 10.

In general,

^(n)C_(r) =

n!r!(n?r)!

,where r ? n, n! = n×(n?1)×...×3×2×1, and 0! = 1.It is not until n = 23, that a value exceeds one-million: ^(23)C_(10) = 1144066.

How many, not necessarily distinct, values of ^(n)C_(r), for 1 ? n ? 100, are greater than one-million?

The only knowledge required in this problem is the binomial coefficient, but its formula is also described in the text above, so we can simply generate all couples (n, r) and check if the value of the binomial coefficient is greater than one million.

In F# this is equivalent to coding a function for the binomial coefficient and testing the items of a sequence:

#light open Microsoft.FSharp.Math let binomial_coefficient n k = BigInt.Factorial n / (BigInt.Factorial k * BigInt.Factorial (n-k)) let answer = seq { for n in 1I .. 100I do for k in 1I .. n -> n,k } |> Seq.filter (fun (a,b) -> binomial_coefficient a b > 1000000I ) |> Seq.length

The approach adopted is almost the same that I used to solve Project Euler problem number 9. It is not the smartest nor the quickest since it is essentially a brute-force algorithm, but without any doubt it is the easiest to implement.

Which optimizations would you consider?

## Project Euler in F# – Problem 5 (alternative solution)

There was some buzz concerning my last post on **Project Euler Problem 5**, since the solution presented implemented a naive **brute-force** algorithm and its performance was very poor.

In my mind it was only meant to be an introductory article devoted to presenting a first solution to a common problem, the **least common multiple** (LCM) of a set of numbers, and I planned to write a second post (the one you are reading now) to show how a "*smart*" algorithm could lead to outstanding performance.

Let's read the text of the exercise another time:

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?

As we already explained, the exercise just asks us to find the **least common multiple** of all numbers from 1 to 20, and we can compute it by using the greatest common divisor of these numbers.

In fact, we have that:

*lcm (a,b) = a * b / gcd (a,b)*

In order to compute the LCM of the numbers from 1 to 20, we start computing the LCM of the first two numbers (1 and 2) and then we go on computing the LCM of the result and the third element of the sequence. We go on this way until all elements have been included in the computation.

The application of the same function to all elements of a sequence while keeping an "*accumulator*" is called ** folding**, and it is a common practice in functional programming.

Let's look at the code:

#light open Microsoft.FSharp.Math.BigInt // Greater Common Divisor let rec gcd a b = match b with | b when b = 0I -> a | b -> gcd b (a % b) // Least Common Multiple let lcm a b = a * b / (gcd a b) let answer = Seq.fold1 lcm [1I .. 20I]

At line 11 we defined the least common multiple as explained above, while at line 5 we have the implementation of the **Euclidean algorithm** for the **Greatest Common Divisor**.

Then we simply *fold* the *lcm* function on the sequence [1 .. 20] and we get the output.

Do you remember how much time our "*optimized*" algorithm in the last article takes to perform the same calculation? **25 seconds**.

The solution presented here only needs **15 milliseconds**!