いくつかのこと:
- ではなく
Math.round()
、試してみてくださいMath.floor()
。あなたの実装でMath.round()
は、最初の要素 (インデックス 0) と最後の要素は、他のすべての要素 (.5/len 対 1/len) よりも可能性が低くなります。最初の反復では、要素を入力arr.length - 1
することに注意してください。arr.length
required
変数を使用する場合は、デフォルトで配列の長さになるという点で、オプションにすることもできます。shuffle = (arr,
required=arr.length)
- 最後の要素のみをシャッフルした場合でも、配列全体を返します。代わりに戻ることを検討してください
arr[arr.length - required ..]
required
範囲内にない場合はどうなります[0,arr.length]
か?
すべてをまとめる (そしていくつかのセンスを追加する):
shuffle = (arr, required=arr.length) ->
randInt = (n) -> Math.floor n * Math.random()
required = arr.length if required > arr.length
return arr[randInt(arr.length)] if required <= 1
for i in [arr.length - 1 .. arr.length - required]
index = randInt(i+1)
# Exchange the last unshuffled element with the
# selected element; reduces algorithm to O(n) time
[arr[index], arr[i]] = [arr[i], arr[index]]
# returns only the slice that we shuffled
arr[arr.length - required ..]
# Let's test how evenly distributed it really is
counter = [0,0,0,0,0,0]
permutations = ["1,2,3","1,3,2","2,1,3","2,3,1","3,2,1","3,1,2"]
for i in [1..12000]
x = shuffle([1,2,3])
counter[permutations.indexOf("#{x}")] += 1
alert counter