THIS BLOG IS NO LONGER UPDATED, FOR THE NEW CONTENTS VISIT WWW.CLAUDIOCHERUBINO.IT



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?

3 Comments »

claudio on December 7th 2008 in Project Euler

Implementation of RSA in F#

During my university course I had to learn and use two functional programming languages: Haskell and Scheme. I fell in love with the former but I never managed to do the same with the syntax of Scheme and the incredibly huge number of parenthesis you have to type in order for your code to work!

That’s why I decided to steal borrow a short implementation of the RSA algorithm written in Scheme and translate it into F#.

As you may know, RSA is an algorithm used for public-key encryption based on prime numbers and factorization that is widely use on the web to secure e-commerce transactions.

At the end of the following code there is also a working example that can be executed to better understand the steps required to encrypt and decrypt a message (in this case a single number):

#light
// Modulus operator that handles negative numbers correctly
let modulus n m =
  ((n % m) + m) % m

// Greater Common Divisor
let rec gcd a b =
  match b with
  | b when b = 0 -> a
  | b -> gcd b (a % b)  

// extended_gcd = (x,y), such that a*x + b*y = gcd(a,b)
let rec extended_gcd a b =
  if (a % b = 0) then
    (0, 1)
  else
    let (x, y) = extended_gcd b (a % b)
    (y, x - y * (a / b)) 

// modulo_inverse(a,n) = b, such that a*b = 1 [mod n]
let modulo_inverse a n =
  let (x, y) = extended_gcd a n
  modulus x n

// totient(n) = (p - 1)*(q - 1),
// where pq is the prime factorization of n.
let totient p q = (p - 1) * (q - 1)

// square(x) = x^2
let square x = x * x

// modulo-power(base,exp,n) = base^exp [mod n]
let rec modulo_power b exp n =
  if (exp = 0) then
    1
  else
    if (exp % 2 = 1) then
      (((modulo_power b (exp - 1) n) * b) % n)
    else
      ((square (modulo_power b (exp / 2) n)) % n)

// RSA routines.

// A legal public exponent e is between
// 1 and totient(n), and gcd(e,totient(n)) = 1
let is_legal_public_exponent e p q =
  (1 < e) && (e < (totient p q)) && (1 = (gcd e (totient p q)))

// The private exponent is the inverse of the public exponent, mod n.
let private_exponent e p q =
  if (is_legal_public_exponent e p q) then
    modulo_inverse e (totient p q)
  else
    raise (new System.Exception("Not a legal public exponent for that modulus"))

// An encrypted message is c = m^e [mod n]
let encrypt m e n =
  if (m > n) then
    raise (new System.Exception("The modulus is too small to encrypt the message"))
  else
    modulo_power m e n

// A decrypted message is m = c^d [mod n]
let decrypt c d n =
  modulo_power c d n

// RSA example.
let p = 61
let q = 53
let n = p * q
let e = 17
let d = private_exponent e p q
let message = 123
let c = encrypt message e n
let m = decrypt c d n

I think the code presented is self-explainatory and each function is briefly described in the comments, but there is a strange thing that you may have noticed.

The first function I defined is the modulus operator, but F# already has a modulus operator, so why bothering?

Before writing that function I was about to getting crazy, since everything else was already written but the encryption was not working properly. I debugged and tested again and again and eventually I found out that sometimes the result of the native modulo operation was a negative number.

After a short lookup on Wikipedia, I discovered that each programming language implements the modulo operator differently and while in Scheme the result has the same sign as the divisor, in F# the sign of the result is the same as the dividend!

3 Comments »

claudio on December 1st 2008 in Functional programming

Project Euler in F# – Problem 19

When someone asks me what are the advantages of F# in comparison with the other functional programming languages, usually the first thing I answer is the .Net Framework.

This framework provides the developers with a plethora of libraries and functions that cover almost all the requirements you can imagine and if you need something that is missing, you will surely develop it on top of solid basis.

I can prove this by showing you the F# solution to Project Euler problem number 19:

How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

After the first time I read the problem I started wondering on how to check whether a given date is a Sunday and a “smart” solution suddenly came into my mind.

The .Net Framework contains a robust set of classes and functions to work on dates and F# can use them as C#, VB.Net and all the other supported languages.

The algorithm implemented works in the following way: we create a starting DateTime object representing 1 Jan 1901 and then continue adding 1 month (using the AddMonths function) until we get to year 2001.

For each DateTime objects returned by this sequence we check if its DayOfWeek property is equal to DayOfWeek.Sunday (.Net magic!). In this case we keep the value otherwise we simply discard it.

Eventually we just have to count the number of items (i.e. DateTime objects) left and we get the result.

Let’s translate the algorithm into F# syntax and we get the following code:

#light
open System

let startDate = new DateTime(1901, 1, 1)

let euler19 = startDate
              |> Seq.unfold (fun (x : DateTime) -> Some(x, x.AddMonths(1)))
              |> Seq.take_while (fun (x : DateTime) -> x.Year < 2001)
              |> Seq.filter (fun (x : DateTime) -> x.DayOfWeek = DayOfWeek.Sunday)
              |> Seq.length

3 Comments »

claudio on November 19th 2008 in Project Euler

Project Euler in F# – Problem 36

A number (in general a word) is palindromic when it can be read in the same way from left to right and in the opposite direction, i.e. it is “symmetrical“.

According to the definition, a number can be palindromic when written in base10 and not palindromic in base2, but there are some numbers that are palindromic in both bases.

In Project Euler Problem 36 we have to find all these numbers between 1 and 1 million:

The decimal number, 585 = 10010010012 (binary), is palindromic in both bases.

Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2.

(Please note that the palindromic number, in either base, may not include leading zeros.)

To solve this problem we need two helper functions, one to check whether a number is palindromic and another one to convert a number from base10 to base2:

#light
open Microsoft.FSharp.Math

let isPalindromic n =
  let chars = n.ToString().ToCharArray()
  chars = Array.rev chars  

let toBinary (n : BigInt) =
  let rec toBinary1 a v =
    match v with
    | 0I -> a
    | _ ->
      let q,r = BigInt.DivMod (v,2I)
      toBinary1 (r.ToString()::a) q
  toBinary1 [] n |> List.reduce_left (^) |> BigInt.Parse

let euler36 = [1I .. 1000000I] |>
              List.filter isPalindromic |>
              List.filter (fun x -> x |> toBinary |> isPalindromic) |>
              List.reduce_left (+)

The first function checks if a number is palindromic by converting it into an array of digits and checking if this array is equal to its reverse one.

Then we have the toBinary function that is based itself on an inner function called (with a lot of originality) toBinary1.

This recursive function uses the list a to store the remainders of the repeated divisions by 2, until the original number is over.

These digits, converted as strings, are joined with ^, the string concatenation operator and eventually the result is converted to a BigInt.

To find the answer to the problem we start with the list of all numbers between 1 and 1 million and take (filter) only the elements which are palindromic in base10.

After this first step, we filter the list again, this time keeping only those numbers that are palindromic when converted to base2.

The last step is the easiest, we only need to sum the numbers left to get the answer to the problem.

1 Comment »

claudio on October 8th 2008 in Project Euler

Project Euler in F# – Problem 25

After a long break, let’s try to resume with a regular publication scheme, starting with Project Euler’s problem 25, an easy one, which says:

The Fibonacci sequence is defined by the recurrence relation:

Fn = Fn1 + Fn2, where F1 = 1 and F2 = 1.

The 12th term, F12, is the first term to contain three digits.

What is the first term in the Fibonacci sequence to contain 1000 digits?

The problem definition also contains the algorithm to solve it, I told you it was easy.

Actually, we just have to write a function to compute the Fibonacci sequence and stop when a term contains a thousand digits.

Since we don’t know when we are done evaluating the terms of the sequence we have to generate an infinite sequence and check every new item to see if we can stop.

Let’s give a look at the F# code:

#light
open Microsoft.FSharp.Math.BigInt

let has1000Digits (n : Microsoft.FSharp.Math.BigInt) =
  n.ToString().Length = 1000

let euler25 =
  ((1I,1I) |> Seq.unfold
    (fun (n0, n1) ->
      (if has1000Digits n0 then None
        else Some(n0, (n1, n0 + n1))))
    |> Seq.length) + 1

The Seq.unfold function is used to generate the infinite sequence, returning Some when we want to continue and None when we are done searching (i.e. the term has 1000 digits).

In the latter case, the length of the sequence represents the number of elements generated before the one with a thousand digits, so we have to sum 1 to get the desired answer.

4 Comments »

claudio on September 19th 2008 in Project Euler

F# September CTP released!

F# development has finally reached CTP (Community Technology Preview) release and this actually makes F# a first-class citizen in the .Net ecosystem.

Don Syme himself made this important announcement on his blog, where he describes some of the major improvements, that include new and improved F# Project system and language service.

The detailed release notes can be found here, while the installer can be downloaded from the brand new Microsoft F# Developer Center.

No Comments »

claudio on August 31st 2008 in News

Balanced parenthesis

Checking whether a series of parenthesis is balanced and valid is a classic puzzle in computer science and can be easily met during a job interview.

In my opinion, there is no better solution than using a regular expression and solve the problem with a single (but almost unreadable) line of code, however I’d like to describe an algorithm which can be easily implemented in any functional or imperative programming language.

The idea is simple: start from the first character and check if it is an opening parenthesis. In this case we have to push it on a LIFO data structure such as a stack and continue with the next character.

If the character is a closing parenthesis, we take (pop) the top element from the stack and check if it makes a valid couple of brackets with the examined element.

If this is not the case, the series is not balanced, otherwise we can discard both parenthesis and go on with the next character, until the series is over.

When there are no parenthesis left to examine, if the stack is empty our series is valid; if there are still elements on the stack we can conclude that the series is unbalanced.

Lets give a look at the F# implementation I wrote to answer Dev102’s challenge:

#light

let brackets = [('(',')'); ('[',']'); ('{','}'); ('<','>')]

let is_opening bracket =  List.exists ( fun (a,b) -> a = bracket) brackets
let is_closing bracket =  List.exists ( fun (a,b) -> b = bracket) brackets
let is_valid (opening, closing) = List.exists (fun (a,b) -> (a,b) = (opening, closing)) brackets

let rec check_valid stack char_array  =
   match char_array with
   | [] -> stack = List.Empty
   | c::cs when is_opening c -> check_valid (c::stack) cs
   | c::cs ->
      match stack with
      | [] -> false
      | x::xs when is_valid (x, c) -> check_valid xs cs
      | x::xs -> false

At the beginning I defined the list of valid couples and three functions to check respectively if a char is an opening or closing bracket or if a couple is valid.

After that there is a function implementing the algorithm explained above. The stack is just a normal list, where items are always added and removed from the front.

5 Comments »

claudio on July 22nd 2008 in Functional programming

The missing number

There is an interesting series of programming job interview challenges proposed by Dev102.com, which is now at its tenth puzzle:

This week question is pretty easy. Your input is an unsorted list of n numbers ranging from 1 to n+1, all of the numbers are unique, meaning that a number can’t appear twice in that list. According to those rules, one of the numbers is missing and you are asked to provide the most efficient method to find that missing number. Notice that you can’t allocate another helper list, the amount of memory that you are allowed to allocate is O(1). Don’t forget to mention the complexity of your algorithm…

I’m not sure I understood correctly the constraint related to the memory allocation.

In my opinion, when they say we are limited to O(1), they mean that we can only allocate a single numeric variable and not any other data structure.

According to this interpretation, the solution is quite easy.

First of all, we take our only variable and store into it the sum of all the numbers between 1 and n + 1, which can be easily computed remembering that 1 + 2 + … + n = n (n + 1) / 2.

Then, we subtract each element of the array from this value, eventually the result is actually our missing number.

The functional implementation of this imperative algorithm is straightforward:

#light

let sum n = ((n + 1) * (n + 2)) / 2

let answer nums = (nums |> List.length |> sum) - (List.reduce_left (+) nums)

Let’s talk about the complexity of the algorithm.

If the length of the input list list is known, evaluating the sum of the first n natural numbers takes O(1), otherwise we have to scan the entire list, i.e. O(n).

Then we have to subtract each element of the list, and this takes another iteration, so another O(n).

Therefore we have O(n) + O(n), which is definitely O(n), and can be easily optimized a little by scanning the list only once.

The only problem left is: “am I following the instructions“?

13 Comments »

claudio on July 1st 2008 in Functional programming

Google Interview Question: Product of other Elements in an Array in O(n)

Last time I was interviewed for a software development engineer position, the recruiter asked me some of the classical Microsoft interview questions, such as “How Would You Move Mount Fuji?” or “How many gas station are there in your country?“.

It was the first time for me to be asked such questions but having obtained the job I think my answers were good enough.

After that day, I looked for other well-known interview questions and I discovered that Google has a totally different approach, focusing on algorithms, data structures and complexity.

For instance, one of Google interview questions says:

There is an array A[N] of N integers. You have to compose an array Output[N+1] such that Output[i] will be equal to the product of all the elements of A[] except A[i].

Example:
INPUT:[4, 3, 2, 1, 2]
OUTPUT:[12, 16, 24, 48, 24]

Solve it without division operator and in O(n).

Without the two constraints at the end of the puzzle it would have been straightforward, but now we have to be smart.

Actually, the product of all elements of A[] except A[i] is equal to the product of all elements before A[i] and those after A[i].

We can traverse A[] twice, once from left to right and once in the opposite way and multiply all the elements we find before A[i].

We’ll pretend to have a new array called Output[] to store the output of the first pass, assigning Output[i] the product of all elements preceding A[i]:

let rec firstpass product input =
    match input with
    | [] -> []
    | x::xs -> product :: firstpass (product * x) xs

For the second pass we need to move from right to left, but this can be done by reversing the input arrays and moving as usual:

let secondpass product input arr =
    let rev_input = List.rev input
    let rev_arr = List.rev arr
    let rec rev_secondpass product (input:list<int>) arr =
      match arr with
      | [] -> []
      | x::xs -> rev_secondpass (product * input.Head) input.Tail xs @ [(x * product)]

    rev_secondpass product rev_input rev_arr

Both firstpass and secondpass expect an integer argument called product, which will be always be 1 at the beginning and will be used to store the intermediate products during the recursive calls.

With these functions we can just define an input array and apply them to get the result.

The following is the complete F# code:

#light

let input = [ 4; 3; 2; 1; 2 ]

let answer values = 

  let rec firstpass product input =
    match input with
    | [] -> []
    | x::xs -> product :: firstpass (product * x) xs

  let secondpass product input arr =
    let rev_input = List.rev input
    let rev_arr = List.rev arr
    let rec rev_secondpass product (input:list<int>) arr =
      match arr with
      | [] -> []
      | x::xs -> rev_secondpass (product * input.Head) input.Tail xs @ [(x * product)]

    rev_secondpass product rev_input rev_arr

  values |> firstpass 1 |> secondpass 1 values

10 Comments »

claudio on June 10th 2008 in Functional programming

Google Treasure Hunt 2008, second puzzle in F#

Unlike the first puzzle, which required some maths knowledge, in the second one we have to prove to be able to recursively process the filesystem.

I think that this puzzle should be quite easy to solve for the system administrators and in general those used to scripting languages.

Here is the text of the second Google Treasure Hunt 2008 problem:

Here is a random zip archive for you to download:
GoogleTreasureHunt08_1767743498252291641.zip

Unzip the archive, then process the resulting files to obtain a numeric result. You’ll be taking the sum of lines from files matching a certain description, and multiplying those sums together to obtain a final result. Note that files have many different extensions, like ‘.pdf’ and ‘.js’, but all are plain text files containing a small number of lines of text.

Sum of line 4 for all files with path or name containing jkl and ending in .txt
Sum of line 1 for all files with path or name containing zzz and ending in .xml
Hint: If the requested line does not exist, do not increment the sum.

Multiply all the above sums together and enter the product below.

As usual, the puzzle may seem challenging at a first glance, so it is important to break it into smaller (and simpler) pieces.

First of all, we have to get the list of files ending with a given extension and containing a specific substring in their name.

There is an overloaded version of the Directory.GetFiles() function which takes two parameters, the directory to be searched and a pattern to be found in the files.

Then we have to filter the results checking if the complete filenames (path + filename) contain the given substring.

This first sub-problem can be solved with the following F# code:

#light
open System.IO

let file_list dir pattern content =
  let rec allFiles dir pattern =
      seq
          { for file in Directory.GetFiles(dir, pattern) do
              yield file
            for subdir in Directory.GetDirectories(dir) do
              for file in allFiles subdir pattern do
                  yield file }
  let elems = allFiles dir pattern
  let filt (str : string) = str.Contains(content)
  Seq.filter filt elems

Now we have the list of all files that satisfy the requirements of the exercise.

The next step is to open them (they are plain text files, despite their extensions) and take the numeric value from the right line, if present.

Let’s write a function to accomplish this task for a single file and then map it to the entire list:

let getvalue numline filename =
  let lines = File.ReadAllLines(filename)
  let linevalue (lines : string[]) numline =
    let realindex = numline - 1
    if lines.Length > realindex then
      System.Int32.Parse(lines.[realindex])
    else
      0
  linevalue lines numline

The File.ReadAllLines(filename) function returns an array of strings, one for each line of the source file.

Arrays in F# have indexes starting from 0, so we have to subtract 1 from the line number supplied by the user to get the real index.

We also have to be sure that the searched line exists. In this case we return its content, otherwise we return zero.

We have now all the elements we need to compute one of the numbers requested by the exercise, we should only supply the appropriate parameters in this way:

let treasurehunt2 dir pattern content numline =
  file_list dir pattern content |> Seq.map (getvalue numline) |> Seq.fold (+) 0

For instance, to solve the first line of my puzzle we have to run the following command, assuming that the archive was unzipped in C:\google:

treasurehunt2 "C:\google" "*.txt" "jkl" 5

I hope you don’t need my help to run this command twice with different parameters and multiply the results to get your answer to the quiz!

10 Comments »

claudio on May 21st 2008 in Functional programming