Assuming that Math.random()
produces evenly distributed random numbers between 0 and 1, is this a correct implementation of the Fischer Yates shuffle? I am looking for a very random, even distribution, where the number of shuffled elements in an input array (arr
) can be specified (as required
).
shuffle = (arr, required)->
rnd = (int) ->
r = Math.random() * int
Math.round r
len = arr.length-1
for i in [len..1]
random = rnd(i)
temp = arr[random]
arr[random] = arr[i]
arr[i] = temp
break if i < len - (required - 2)
return arr
A couple things:
Math.round()
, tryMath.floor()
; in your implementationMath.round()
gives the first element (at index 0) and the last element less of a chance than all the other elements (.5/len vs. 1/len). Note that on the first iteration, you inputarr.length - 1
forarr.length
elements.required
variable, you might as well make it optional, in that it defaults to the length of the array:shuffle = (arr, required=arr.length)
arr[arr.length - required ..]
required
isn't in the range[0,arr.length]
?Putting it all together (and adding some flair):