Skip to main content
2 of 5
edited tags

This code emulates the coin flip problem. Can this be refactored further to become more succinct?

I started playing around recently with F# and I find it quite elegant and succinct language.

A common problem I like to solve in every language I start to learn is the coin flip problem, with the code below being the solution to this particular problem. What the code does is to flip a coin N times and perform M tests for each flip series. Finally, it prints in console a binomial distribution visual.

I am new to F# and I might being hasty here, I probably will learn this myself much later, but is anybody that can suggest a refactoring? Is it possible to make this even more succinct?

I solved the problem with code very similar to imperative style and I refactored my way to the following code, trying keep it as much as declarative as I could.

open System

let heads (random: Random) =
    random.Next(0, 2) = 1

let add x y = x + y

let rec calculateHeads n random =
    match n with
    | 0 -> 0
    | _ -> 
        let result = calculateHeads (n - 1) random
        let addToResult v = add v result
        match heads (random) with
        | true -> addToResult 1
        | false -> addToResult 0

let rec fill frequency n m random =
    match m with
    | v when v < 0 -> frequency
    | _ ->
        let count = calculateHeads n random
        Array.set frequency count (frequency.[count] + 1)
        fill frequency n (m - 1) random

let getFrequencies n m =
    let random = new Random()
    let frequency = Array.create (n + 1) 0
    fill frequency n m random

let rec displayAsterisk length =
    match length with
    | v when v = 1 -> "*"
    | v when v < 1 -> ""
    | _ -> "*" + (displayAsterisk (length - 10))

let rec displayRecursive list =
    match list with
    | [] -> ()
    | head::tail ->
        displayRecursive tail
        printfn "%d%s -- (%d)" head (displayAsterisk (head)) head

let displayCoin (frequency:int[]) =
    displayRecursive (frequency |> Array.toList)

[<EntryPoint>]
let main argv = 
    let frequency = getFrequencies 32 1000
    displayCoin frequency
    0