わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

続・1〜NからM個をランダムに選ぶ

昨日の続きなのですが,いくつかビンゴカードを見て,間違いに気づきました.たとえば「1〜15から5個」取って縦方向に並べる際,数値の順番はばらばらです.昨日のプログラムをそのまま使うと,各列,上から下へ数字が大きくなってしまいます.
修正の方法としては,「array << ofst」のところを,

array.insert(rand(array.size + 1), ofst)

とすればいいようです.arrayが空のとき,rand(1)は仕様により常に0になり,結局「array[0] = ofst」と等価になりますが,ちょっと気持ち悪いですね.
chooseを丸ごと変えてしまうという別解もあります.

def choose(max, pcs, ofst = 1)
  (ofst...(ofst + max)).to_a.shuffle[0, pcs]
end

shuffleは Ruby 1.9で組み込まれたメソッドですが,1.8.7でも使用可能になっています*1.ただし,1.8.7で試したところ,単純なchooseの取り換えでは,何度実行しても,同じ結果になります.実行の初めに「srand」を入れれば*2,変わりました.randでは暗黙のsrandがありますが,shuffleでは明示しないといけないようです.
字数はなるべく減らしています.「(ofst...(ofst + max))」は「(ofst..(ofst + max - 1))」と同じです.ofstが1,maxが15なら,いずれも「1〜15のRangeオブジェクト」となります.shuffleの直後の「[0, pcs]」は,shuffleの引数ではなく,shuffleにより得られた配列の先頭pcs個を取り出すものです.
うーん,まだビンゴカード生成にたどりつけません.明日こそ.