配列シャッフル
単純で正しそうなものが正しいとは限らない - Radium Software
英語のもとページ読んでないけど。
インデックスを足していくか引いていくかはどうでもよくて、むしろ本質が紛らわしくなってる気がする。
def shuffle1(a) a.size.times{|i| n = rand(a.size) t = a[i]; a[i] = a[n]; a[n] = t } a end def shuffle2(a) a.size.times{|i| n = i + rand(a.size - i) t = a[i]; a[i] = a[n]; a[n] = t } a end def test cards = 1..4 h = Hash.new{0} 100000.times{ a = yield(cards.to_a) h[a[0]]+=1 } p h end p "shuffle1" test{|cards| shuffle1(cards)} p "shuffle2" test{|cards| shuffle2(cards)}
ruby shuffle.rb "shuffle1" {1=>24886, 2=>29201, 3=>24514, 4=>21399} "shuffle2" {1=>24809, 2=>25052, 3=>25215, 4=>24924}
俺的ナイーブなシャッフルは、配列からランダムな要素を切り出して新しい配列を作る感じ。
def shuffle3(a) b = a.dup ret = [] until b.empty? ret << b.slice!(rand(b.size)) end ret end
メモリがーとかは考えません。安いから買え。