1〜100の整数をランダムに並び替え
ランダムに並んだ1〜100の整数に用があった。
取り急ぎ、思いつくまま作ってみる。
max=100 a=Array.new while a.size<max i=rand(max)+1 a<<i if not a.include?i end
1〜100の整数がユニークに揃うまで、100以下の乱数を発生させ続ける。ループ回数は確率任せという乱暴な手口だが、レンジが1〜100なら実行時間はたかが知れる。
ループを一定回数にするなら、あらかじめ用意した1〜100の配列をランダムに取り出して並べ直せばいい。
max=100 a=Array.new b=[*(1..max)] 1.upto(max){|i|a<<b.slice!(rand(max-i))}
破壊的メソッドArray#slice!で配列bの任意位置の要素を切り出す。指定位置は、maxからiを引くことでループ毎に配列bが削られていく分を補正する。
むろん、n回のループで1〜nが揃う方がいいので、下の方が無駄がない。
……のだが、maxが3回参照されるのは違和感がある。maxは、配列b自身が自分の配列長として知る情報だ。同様に(max-i)もまた、b自身が知っている情報であるはず。
max=100 a=Array.new b=[*(1..max)] 1.upto(b.size){a<<b.slice!(rand(b.size-1))}
とか、こねくり回してたら。
a=[*(1..100)].sort{rand(3)-1}
こんなんでいいことに気がついた。