0

I am learning F# and would like to know if the following logic to generate random numbers is acceptable.

Could this be written in a more maintainable fashion? Is this code safe?

let hashset = System.Collections.Generic.HashSet<int>()
let mutable continueLooping = true

while (continueLooping) do 
   let value = System.Random().Next(0, 12)
   let success = hashset.Add(value)
   continueLooping <- hashset.Count <> 12

UPDATE

let hashset = System.Collections.Generic.HashSet<int>()
let randomGenerator = System.Random()
let mutable continueLooping = true
let expectedLength = 12

while (continueLooping) do 
   let value = randomGenerator.Next(0, expectedLength)
   let success = hashset.Add(value)
   continueLooping <- hashset.Count <> expectedLength
Scott Nimrod
  • 11,206
  • 11
  • 54
  • 118

1 Answers1

4

You could define a helper function to perform a Fisher-Yates shuffle. This shuffle function is pretty generally useful since it will work on any seq<'a> so you have plenty of opportunities to reuse it.

// shuffle a sequence into random order
let shuffle xs =
    // swap two elements in the supplied array
    let swap i j (array : _[]) =
        let tmp = array.[i]
        array.[i] <- array.[j]
        array.[j] <- tmp
    let rnd = System.Random()
    let xArray = Seq.toArray xs
    let n = Array.length xArray
    for i in [0..(n-2)] do
        let j = rnd.Next(i, n-1)
        swap i j xArray
    xArray |> Seq.ofArray

Then just apply it to a list or something using

let shuffledList = [0..11] |> shuffle |> Seq.toList
TheInnerLight
  • 12,034
  • 1
  • 29
  • 52