Simulating coin flips and plotting a histogram

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
5
down vote

favorite












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






share|improve this question



























    up vote
    5
    down vote

    favorite












    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






    share|improve this question























      up vote
      5
      down vote

      favorite









      up vote
      5
      down vote

      favorite











      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






      share|improve this question













      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








      share|improve this question












      share|improve this question




      share|improve this question








      edited May 26 at 5:30









      200_success

      123k14143399




      123k14143399









      asked May 25 at 23:25









      gdyrrahitis

      1284




      1284




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          I had some smaller points to make on several aspects of your code but I won't mention them since the whole thing can be written more idiomatic and simple style without using any recursion or mutation.



          Note the use of Seq.sumBy and Array.countBy to cut down on a lot of the work:



          let random = System.Random()

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

          let calculateHeads n =
          1 .. n |> Seq.sumBy (fun _ -> if heads () then 1 else 0)

          let getFrequencies n m =
          let counts =
          Array.init m (fun _ -> calculateHeads n)
          |> Array.countBy id
          |> Map
          Array.init (n + 1) (fun i -> counts.TryFind i |> Option.defaultValue 0)

          let displayCoin frequency =
          for c in frequency do
          printfn "%d%s -- (%d)" c (String.replicate (c / 10) "*") c

          let frequency = getFrequencies 32 1000
          displayCoin frequency


          I also made random a module level value instead of passing it around everywhere. The downside of this is you can't test individual functions deterministically.



          If you're not already doing so, you should send code to F# interactive in your IDE to get a much faster feedback cycle for trying out ideas and exploring data.






          share|improve this answer





















          • Just a minor fix, on displayCoin method, it should print the current index in array, so it'd look like this: let displayCoin (frequency:int) = for i = 0 to frequency.Length - 1 do let value = frequency.[i] printfn "%d%s -- (%d)" i (String.replicate (value / 10) "*") value Great answer nonetheless, simplifies my code greatly!
            – gdyrrahitis
            May 27 at 22:13











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195190%2fsimulating-coin-flips-and-plotting-a-histogram%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          2
          down vote



          accepted










          I had some smaller points to make on several aspects of your code but I won't mention them since the whole thing can be written more idiomatic and simple style without using any recursion or mutation.



          Note the use of Seq.sumBy and Array.countBy to cut down on a lot of the work:



          let random = System.Random()

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

          let calculateHeads n =
          1 .. n |> Seq.sumBy (fun _ -> if heads () then 1 else 0)

          let getFrequencies n m =
          let counts =
          Array.init m (fun _ -> calculateHeads n)
          |> Array.countBy id
          |> Map
          Array.init (n + 1) (fun i -> counts.TryFind i |> Option.defaultValue 0)

          let displayCoin frequency =
          for c in frequency do
          printfn "%d%s -- (%d)" c (String.replicate (c / 10) "*") c

          let frequency = getFrequencies 32 1000
          displayCoin frequency


          I also made random a module level value instead of passing it around everywhere. The downside of this is you can't test individual functions deterministically.



          If you're not already doing so, you should send code to F# interactive in your IDE to get a much faster feedback cycle for trying out ideas and exploring data.






          share|improve this answer





















          • Just a minor fix, on displayCoin method, it should print the current index in array, so it'd look like this: let displayCoin (frequency:int) = for i = 0 to frequency.Length - 1 do let value = frequency.[i] printfn "%d%s -- (%d)" i (String.replicate (value / 10) "*") value Great answer nonetheless, simplifies my code greatly!
            – gdyrrahitis
            May 27 at 22:13















          up vote
          2
          down vote



          accepted










          I had some smaller points to make on several aspects of your code but I won't mention them since the whole thing can be written more idiomatic and simple style without using any recursion or mutation.



          Note the use of Seq.sumBy and Array.countBy to cut down on a lot of the work:



          let random = System.Random()

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

          let calculateHeads n =
          1 .. n |> Seq.sumBy (fun _ -> if heads () then 1 else 0)

          let getFrequencies n m =
          let counts =
          Array.init m (fun _ -> calculateHeads n)
          |> Array.countBy id
          |> Map
          Array.init (n + 1) (fun i -> counts.TryFind i |> Option.defaultValue 0)

          let displayCoin frequency =
          for c in frequency do
          printfn "%d%s -- (%d)" c (String.replicate (c / 10) "*") c

          let frequency = getFrequencies 32 1000
          displayCoin frequency


          I also made random a module level value instead of passing it around everywhere. The downside of this is you can't test individual functions deterministically.



          If you're not already doing so, you should send code to F# interactive in your IDE to get a much faster feedback cycle for trying out ideas and exploring data.






          share|improve this answer





















          • Just a minor fix, on displayCoin method, it should print the current index in array, so it'd look like this: let displayCoin (frequency:int) = for i = 0 to frequency.Length - 1 do let value = frequency.[i] printfn "%d%s -- (%d)" i (String.replicate (value / 10) "*") value Great answer nonetheless, simplifies my code greatly!
            – gdyrrahitis
            May 27 at 22:13













          up vote
          2
          down vote



          accepted







          up vote
          2
          down vote



          accepted






          I had some smaller points to make on several aspects of your code but I won't mention them since the whole thing can be written more idiomatic and simple style without using any recursion or mutation.



          Note the use of Seq.sumBy and Array.countBy to cut down on a lot of the work:



          let random = System.Random()

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

          let calculateHeads n =
          1 .. n |> Seq.sumBy (fun _ -> if heads () then 1 else 0)

          let getFrequencies n m =
          let counts =
          Array.init m (fun _ -> calculateHeads n)
          |> Array.countBy id
          |> Map
          Array.init (n + 1) (fun i -> counts.TryFind i |> Option.defaultValue 0)

          let displayCoin frequency =
          for c in frequency do
          printfn "%d%s -- (%d)" c (String.replicate (c / 10) "*") c

          let frequency = getFrequencies 32 1000
          displayCoin frequency


          I also made random a module level value instead of passing it around everywhere. The downside of this is you can't test individual functions deterministically.



          If you're not already doing so, you should send code to F# interactive in your IDE to get a much faster feedback cycle for trying out ideas and exploring data.






          share|improve this answer













          I had some smaller points to make on several aspects of your code but I won't mention them since the whole thing can be written more idiomatic and simple style without using any recursion or mutation.



          Note the use of Seq.sumBy and Array.countBy to cut down on a lot of the work:



          let random = System.Random()

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

          let calculateHeads n =
          1 .. n |> Seq.sumBy (fun _ -> if heads () then 1 else 0)

          let getFrequencies n m =
          let counts =
          Array.init m (fun _ -> calculateHeads n)
          |> Array.countBy id
          |> Map
          Array.init (n + 1) (fun i -> counts.TryFind i |> Option.defaultValue 0)

          let displayCoin frequency =
          for c in frequency do
          printfn "%d%s -- (%d)" c (String.replicate (c / 10) "*") c

          let frequency = getFrequencies 32 1000
          displayCoin frequency


          I also made random a module level value instead of passing it around everywhere. The downside of this is you can't test individual functions deterministically.



          If you're not already doing so, you should send code to F# interactive in your IDE to get a much faster feedback cycle for trying out ideas and exploring data.







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered May 26 at 11:04









          TheQuickBrownFox

          38116




          38116











          • Just a minor fix, on displayCoin method, it should print the current index in array, so it'd look like this: let displayCoin (frequency:int) = for i = 0 to frequency.Length - 1 do let value = frequency.[i] printfn "%d%s -- (%d)" i (String.replicate (value / 10) "*") value Great answer nonetheless, simplifies my code greatly!
            – gdyrrahitis
            May 27 at 22:13

















          • Just a minor fix, on displayCoin method, it should print the current index in array, so it'd look like this: let displayCoin (frequency:int) = for i = 0 to frequency.Length - 1 do let value = frequency.[i] printfn "%d%s -- (%d)" i (String.replicate (value / 10) "*") value Great answer nonetheless, simplifies my code greatly!
            – gdyrrahitis
            May 27 at 22:13
















          Just a minor fix, on displayCoin method, it should print the current index in array, so it'd look like this: let displayCoin (frequency:int) = for i = 0 to frequency.Length - 1 do let value = frequency.[i] printfn "%d%s -- (%d)" i (String.replicate (value / 10) "*") value Great answer nonetheless, simplifies my code greatly!
          – gdyrrahitis
          May 27 at 22:13





          Just a minor fix, on displayCoin method, it should print the current index in array, so it'd look like this: let displayCoin (frequency:int) = for i = 0 to frequency.Length - 1 do let value = frequency.[i] printfn "%d%s -- (%d)" i (String.replicate (value / 10) "*") value Great answer nonetheless, simplifies my code greatly!
          – gdyrrahitis
          May 27 at 22:13













           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195190%2fsimulating-coin-flips-and-plotting-a-histogram%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Python Lists

          Aion

          JavaScript Array Iteration Methods