Tag Archives: algorithms

Project Euler Problem 10 in F#

This problem is very similar to several of the other prime generation problems, but being the dedicated blogger that I am here is problem 10:

The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.

Find the sum of all the primes below two million.

  1. Generate primes using Sieve of Eratosthenes.
  2. Stop before reaching 2 million.
  3. Find the sum of this set of primes.

type public PrimesGenerator() =

member this.getPrimesMax max =

let primes = new BitArray(max+1, true)

let result = new ResizeArray(max/10)

for n = 2 to max do

if primes.[n] then

let start = (int64 n * int64 n)

if start < int64 max then

let i = ref (int start)

while !i <= max do primes.[!i] <- false; i := !i + n

result.Add n

result

member this.Problem9() =

let primesGen = new PrimesGenerator()

primesGen.getPrimesMax 2000000 |> Seq.map (fun prime -> (int64)prime) |> Seq.sum

Download the source code with unit tests.

Advertisements

Project Euler Problem 9 in F#

In the continuing series of solving Project Euler problems with F#, here is problem 9 with my solution:

A Pythagorean triplet is a set of three natural numbers, a b c, for which,

a2 + b2 = c2
For example, 32 + 42 = 9 + 16 = 25 = 52.

There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.

  1. Enumerate from 1 to 1000.  Create tuples of all sets (m, n) where m > n.
  2. Create Pythagorean triplets using Euclid’s formula from the tuples.
  3. Find the set where a + b + c = 1000.
  4. Find the product of this set.
let problem9 =
    let pythagorean_triplets(m:int, n:int) =
        let a = m*m-n*n
        let b = 2*m*n
        let c = m*m+n*n
        [a;b;c]
    let tops = 1000
    [for m in [1..tops] do
        for n in [1..m-1] do yield (m, n)] |> Seq.map (fun t -> pythagorean_triplets((fst t, snd t)))
            |> Seq.filter (fun x -> x |> Seq.sum = tops) |> Seq.head |> Seq.fold (fun acc elem -> acc * elem) 1

Download the source code with unit tests.

Project Euler Problem 8 in F#

In the continuing series of solving Project Euler problems with F#, here is problem 8 and my solution:

Find the greatest product of five consecutive digits in the 1000-digit number.

73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450

  1. Parse the input string to a list of integers
  2. Create lists of each 5 consecutive digits.
  3. Find the product of each list.
  4. Find the max product.
open System

let Problem8 =
    let multiply lst = lst |> Seq.fold (fun acc elem -> acc * elem) 1
    let s = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"
    let values = s.ToCharArray() |> Seq.map (fun x -> Int32.Parse(x.ToString())) |> Seq.toList
    [0..(values.Length - 5)]
        |> Seq.map (fun h -> [0..4] |> Seq.map (fun a -> values.[(h + a)]) |> multiply )
        |> Seq.max

Download the source code with unit tests.

Project Euler Problem 6 in F#

In the continuing series of solving Project Euler problems with F#, here is problem 6 and my solution:

The sum of the squares of the first ten natural numbers is,

12 + 22 + … + 102 = 385
The square of the sum of the first ten natural numbers is,

(1 + 2 + … + 10)2 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 – 385 = 2640.

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

  1. Enumerate 1-100 and  square each value.  Add the results together
  2. Enumerate 1-100 and add each value together.  Square the resulting sum.
  3. Find the difference between the two.
let problem6 = 
    let values = [1..100]
    let sumOfSquares = values |> Seq.map (fun x -> pown x 2) |> Seq.sum
    let squareOfSums = values |> Seq.sum |> (fun x -> pown x 2)
    squareOfSums - sumOfSquares

Download the source code with unit tests.

Project Euler Problem 4 in F#

In the continuing series of solving Project Euler problems with F#, here is problem 4 and my solution:

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 ×99.

Find the largest palindrome made from the product of two 3-digit numbers.

  1. Create the set of all products of two 3-digit numbers.
  2. Filter the values that are palindromes.
  3. Find the max of the palindrome values.
open System

let problem4 =
    let reverseNumber value = Convert.ToInt32(new string(Array.rev (value.ToString().ToCharArray())))
    [for i in [100..999] do
        for j in [100..999] do yield i * j]
            |> Seq.filter (fun x -> x = reverseNumber(x)) |> Seq.max

Download the source code with unit tests.

Project Euler in F#, Problems 1 and 2

I recently stumbled across the Project Euler website. From wikipedia: “Project Euler (named after Leonhard Euler) is a website dedicated to a series of computational problems intended to be solved with computer programs”.

I thought this would be a good opportunity to continue working with F# and have some material for writing more blog articles.

Problem 1 is very straight forward.

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

I went with the most logical algorithm I could think of.

  1. Enumerate though each of the numbers 1-999.
  2. Filter the values that are multiples of either 3 or 5.
  3. Add up the resulting values.

The resulting F# code is quite elegant:

let problem1 = 
    [1..999] |> Seq.filter (fun i -> i % 3 = 0 || i % 5 = 0) |> Seq.sum

After looking at other algorithms people had used, there are more efficient methods using summations. But not bad for my first solution. On to problem 2

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

Again, there is a pretty obvious solution here.

  1. Generate the Fibonacci sequence up to 4 million.
  2. Filter the values that are even.
  3. Add up the resulting values.

The resulting F# code:

let Problem2 =
    Seq.unfold (fun state ->
        if (snd state > 4000000) then None
        else Some(fst state + snd state, (snd state, fst state + snd state))) (1,1)
            |> Seq.filter (fun x -> x % 2 = 0) |> Seq.sum

Again, a more efficient solution can be found but this is at least semantically easy to follow.

I’m planning on continuing this series of blog articles with a problem or 2 for each entry, and seeing how many of the problems I can get through.  I’ll also provide the source code.   If you’re interested in more in this series stay tuned!