The Great VB vs F# Euler Shootout Problem 1

I’ve been looking for some little programs to work on in order to learn F#.  Thankfully, I stumbled across Dustin Campbell’s blog, which led me to following site.

http://projecteuler.net

It’s really a lot of fun and a great way to learn F#.  Dustin has been showing the solutions in F# and I’ve run across C# solutions, so I thought I’d compare how to do the problems in F# with how you would do them in Visual Basic. 

Problem 1

 

Add all of the natural number below 1000 that are multiples of 3 or 5.

Problem 1 the F# way

I’m a newbie at F#, so I’ll admit to examining Dustin’s solution right off the bat.  I take no credit for the following F# code.  All I’ve done is update it for the CTP release.

 

let result =

    seq {for n in 1 .. 999 do

            if n % 3 = 0 or n % 5 = 0 then

                yield n}

    |> Seq.reduce (+)

 

printfn “%A” result

 

Let’s examine the parts real quick

·         seq declares we will be using a sequence workflow.

·         for n in 1 .. 999 do generates and iterates through number 1 to 999.

·         if n % 3 = 0 or n % 5 = 0 then checks if n a multiple of 3 or 5

·         yield n returns the result 1 number at a time

·         |> Seq.reduce (+) sums up all the numbers in our generated sequence

 

And when we run our program, the number 233168 gets printed to the console.

 

Problem 1 the VB way

I was going to solve the problem in VB the standard brute force iteration way until I came across the following blog entry.  Again, I take no credit for the following code.  It has been scoffed from another source.

 

Dim result = Enumerable.Range(1, 999).Where(Function(n) n Mod 3 = 0 OrElse n Mod 5 = 0).Sum()

 

Let’s examine the parts real quick

·         Enumerable.Range(1, 999) generates and iterates through number 1 to 999.

·         Where(Function(n) n Mod 3 = 0 OrElse n Mod 5 = 0) checks if n a multiple of 3 or 5.

·         We don’t need to yield the result one number at a time as the implementers of the Where method have already done if for us.

·         Sum() sums up all the numbers in our generated sequence

Not too different from our F# solution.  Linq monads are a form of what F# calls workflows.  If we convert the Linq expression above to the more familiar syntax we get.

 

Dim result = (From n In Enumerable.Range(1, 999) _

              Where (n Mod 3 = 0 OrElse n Mod 5 = 0) _

              Select n).Sum()

 

I really can’t say this is any easier to read than the first example, but they both print 233168 to the console.

 

F# One Ups VB

So if VB can do what F# already does then why learn F#?  Because we can do things like the following.

 

let result =

    seq {for n in 1 .. 999 do

            let (%%) n s = Seq.exists (fun x -> n % x = 0) s

            if n %% [3;5] then

                yield n}

    |> Seq.reduce (+)

 

printfn “%A” result

 

We’ve defined a temporary function in the middle of our workflow that basically means “is a multiple of”.  Now we just pass a list of numbers that we want to check n against. For instance,

if n %% [3;5;7;9] then

would mean, where n is a multiple of 3, 5, 7 or 9.  VB has plans on adding multiline lambdas, but I haven’t heard of any support for defining and using those lambda’s later on in the workflow.  We are allowed to bind functions to identifiers in VB. For instance,

 

let (%%) n s = Seq.exists (fun x -> n % x = 0) s

if n %% [3;5] then

 

can be translated into the following VB

 

Dim multiple_of = Function(n, s) s.Any(Function(x) n Mod x = 0)

Dim seq As New List(Of Integer)

seq.Add(3)

seq.Add(5)

Dim result = multiple_of(3, seq)

 

but we have no way of inserting this function identifier into our LINQ workflow.  It would be nice to be able to do the following

 

Dim result = (From n In Enumerable.Range(1, 999) _

              Dim multiple_of = Function(n, s) s.Any(Function(x) n Mod x = 0) _

              Where (n multiple_of([3;5;7;9]) _

              Select n).Sum()

Someday!

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>