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?
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!
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.
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.
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.
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.
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"?
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.zipUnzip 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!
Google Treasure Hunt 2008, first puzzle in F#
A couple of days ago Google launched a contest called Treasure Hunt 2008, which will be composed of 4 puzzles.
Only the first of these quizzes is already available at http://treasurehunt.appspot.com/, and the new ones will be posted once per week.
At the end of the four puzzles there will be some prizes, even if nothing has been revealed yet.
Here is the description of the first puzzle:
A robot is located at the top-left corner of a n x k grid.
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid.
How many possible unique paths are there?
(Note: Answer must be an exact, decimal representation of the number. Image not to scale.)
If the number of rows is r and the number of columns c, the robot can move r-1 steps down and c-1 steps to the right to get to the bottom-right corner of the grid.
The number we want to find is the combination of r1 and c1, and this can be easily computed using the binomial coeficient:
![]()
Let's assume r1 = r-1 and c1 = c-1, and write some F# code to get the solution to our problem:
#light open Microsoft.FSharp.Math.BigInt let robot rows columns = let r1 = rows - 1I let c1 = columns - 1I (factorial (r1 + c1)) / ((factorial r1) * (factorial c1))
This first puzzle was very easy to solve, if you go to the Treasure Hunt website now, you'll find the next exercise.
I'll give it a try, if you are interested just drop a comment and we'll discuss it here.
Project Euler in F# – Problem 48
The following problem from Project Euler is one of those supposed to be solved either with intensive computation or a "smarter" approach.
Here is the description of problem number 48:
The series, 1^1 + 2^2 + 3^3 + ... + 10^10 = 10405071317.
Find the last ten digits of the series, 1^1 + 2^2 + 3^3 + ... + 1000^1000.
If our language allows us to evaluate the series mentioned above (and F# does!), we can just do it and then take the last 10 digits of the result as required.
This can be implemented by the following F# code:
#light open Microsoft.FSharp.Math.BigInt let last10 num = num % (pow 10I 10I) let answer = [1I .. 1000I] |> Seq.map (fun x -> pow x x) |> Seq.fold (+) 0I |> last10
The first problem is extracting the last ten digits from a given number, and this is done by dividing the number by 10^10 and returning the remainder of the division (line 4).
Then we have to generate the series n^n for all n from 1 to 1000 and sum the items.
This sum is actually a huge number (more than 3000 digits) but we are only interested in the last ten digits, so we can use the pipeline operator (|>) to pass it to the last10 function.
The only caveat is to use BigInt, otherwise the numbers we are talking about will never fit into the other numeric data types.
Easy, isn't it?



