Friday, June 15, 2007

F# FizzBuzz

I'm trying to learn F# as the "pragmatic-learn-a-new-changing-the-way-you-think-programming-language-every-year" (sorry about that, it must be the german influence).

Here are my FizzBuzz exercises, based on F# Active Patterns:

First try:

let (| fizz|_ |) x = if x % 3 = 0 then Some("fizz") else None

let (| buzz|_ |) x = if x % 5 = 0 then Some("buzz") else None

let (| fizzbuzz|_ |) x = if x % 15 = 0 then Some("fizzbuzz") else None

let print_fizzbuzz (x:int) =

let display text = print_string text; print_newline() in

match x with

| fizzbuzz text -> display text

| fizz text -> display text

| buzz text -> display text

| _ -> x.ToString() |> display

let _ = for i = 1 to 20 do print_fizzbuzz i done



Second try: refactor the recognizers to a single parameterized recognizer:


let (| is_multiple|_ |) n text x = if x % n = 0 then Some(text) else None

let print_fizzbuzz (x:int) =

let display text = print_string text; print_newline() in

match x with

| is_multiple 15 "fizzbuzz" text -> display text

| is_multiple 5 "fizz" text -> display text

| is_multiple 3 "buzz" text -> display text

| _ -> x.ToString() |> display

let _ = for i = 1 to 20 do print_fizzbuzz i done


(* we do get a warning that the syntax for the parameterized recognizers is under review and it might change in the future release *)

Please post or backlink for improvements :D

2 comments:

Robert Pickering said...

Nice implementation. While I like the use of active patterns for a very simple implementation like this they probably add more overhead than they give benefit.

Also I think the #light which makes F# whitespace senative is great. Here's my effort:

#light

for x in [1 .. 20] do
match x with
| x when x % 15 = 0 -> printfn "fizzbuzz"
| x when x % 3 = 0 -> printfn "fizz"
| x when x % 5 = 0 -> printfn "buzz"
| x -> printfn "%i" x

Andrei Pamula said...

Hi Robert,
thanks for the contribution. It looks very clean.