A blog about SQL Server, SSIS, C# and whatever else I happen to be dealing with in my professional life.

Find ramblings

Showing posts with label F#. Show all posts
Showing posts with label F#. Show all posts

Saturday, September 12, 2009

Project Euler, Problem 1

Problem 1 for Project Euler was to "Add all the natural numbers below one thousand that are multiples of 3 or 5." Logically, it's a simple enough problem: for each number between 3 and 999, if it is evenly divisible by 3 or 5, we will need to put in our running total. The challenge for me is getting into the whole mindset of functional programming. I can't wait to compare this first solution to what I'll hopefully be writing in a few months.



#light

open System
// open Microsoft.FSharp.Collections.Set

// 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.


let rec threeMultiples n =
if n = 3 then [3]
else if n % 3 = 0 then threeMultiples(n-1) @ [n]
else threeMultiples(n-1)

let rec fiveMultiples n =
if n = 5 then [5]
else if n % 5 = 0 then fiveMultiples(n-1) @ [n]
else fiveMultiples(n-1)

// Define the upper limit of where we are looking
let ceiling = 1000 - 1

// generate a list of all the natural numbers less than ceiling
// evenly divisible by 3 or 5.
// TODO: Understand how to pass 2 params to recursive fxn
let tempList = threeMultiples ceiling @ fiveMultiples ceiling

// Convert our list to a set to eliminate the duplicate values
let setList = Set.of_list tempList

// Convert the set back to a list so we can accumulate them
let sumList = Set.to_list setList

// Sum them numbers up
// You//s a big fine function,
// won//t you sum them numbers up
// Original lyrics by Juvenile (1999)
// Insipid comments like the above are why I should be sleeping
let sums = List.sum sumList

System.Console.WriteLine(String.Format("Sum of the natural numbers divisible by 3 and 5 under {0} is {1}", ceiling, sums))

Now I can sleep

Friday, September 11, 2009

F# declaration loop-de-loop

Just a quick note as it's late and I should have been in bed a few hours ago, but

let ceiling = 1000 -1

fails with "This value is not a function and cannot be applied" Why? The whitespace. As it parses now, F# is attempting to call the 1000 function with a parameter of -1*. If either the space between the 0 and - is removed or if an extra space is inserted between the - and the 1, then it will work. F# doesn't know what to do with negative one, but does know how to add negative one to 1000. Any of the following three would work

let ceiling1 = 1000-1
let ceiling2 = 1000 - 1
let ceiling3 = 1000 + -1
*At least, that's my guess. Seems reasonable enough at this point

F you

I'm talking about F#, what'd you think I was talking about? I can't tell if it's, Functional programming itself or F# that's causing me more pain. I wasn't blessed to deal with Lisp or a derivative in college so it's only as an adult that I'm trying to wrap my brain around it. Imperative and declarative programming, I think I have down solid. Python and this Johnny-come-lately C# led me to believe I should be okay with the concepts of functional programming. Visual Studio 2010 has full-fledged support for F# and a nifty tutorial which compiles and runs just fine. However, my ability to crib from that to build out my own solutions for Project Euler has been less than spectacular. After starting complex, I've distilled my problem down to "how do I append another element to a list." The damnable thing, is that they have an example right there in the tutorial of how to do it in F#.


#light
// List of best friends.
let bffs = [ "Susan"; "Kerry"; "Leslie"; "Maria" ]

// Bind newBffs to a new list that has "Ginger" as its first element.
let newBffs = "Ginger" :: bffs


Monkey see, monkey do but I wanted to work with integers and append an integer to the end.


// List first fibbonaci numbers.
let fib = [ 1; 1; 2; 3; 5; 8 ]

// Bind fibNext to a new list that has 13 as its last element.
let fibNext = fib :: 13


That throws a syntax error though: "This expression has type int but is here used with type int list list" Some hits with Google for that but no one seems to have as elementary of a sample as I'm working with. Logically, it makes me think the type is wrong with 13.


// List first fibbonaci numbers.
let fib = [ 1; 1; 2; 3; 5; 8 ]
let thirteen = [ 13 ]

// Bind fibNext to a new list that has 13 as its last element.
let fibNext = fib :: thirteen

That results in the even more maddening error of "Type mismatch. Expecting a int list list but given a int list. The type 'int list' does not match the type 'int'" Sooo, it's expecting an int list list but I only gave it an int list... However, it's at least list-like so thanks to this link I at least see that I can concat two lists with the @ operator so the following compiles so it must work

let fibNext = fib @ thirteen

Blessedly, it does and I'm back in to defiling F# with my unwashed hands. TODO: find and read an article like Dive into Python for F#