Ruby1.9のArray#sampleを使ってビンゴカードを作る。
別にビンゴカードを作りたいわけじゃないけど、Ruby1.9のArray#sampleの使いどころを考えてたらビンゴカードが思い浮かんだのでやってみました。
最初は単純に
(1..75).to_a.sample(24)
で良いのかなーと思ったんですけど、wikipediaを読んでみたら
なお、通常はまったくのランダムで番号が書かれているわけではなく、一番左の列は1~15の数字の中から5個選ばれている。同様に、左から2列目は16~30、中央列は31~45、右から2列目は46~60、一番右の列は61~75から5個ずつ選ばれている。
ビンゴ - Wikipedia
って書いてあったので、そのあたりも踏まえつつ、Array#sampleを使ってビンゴカードを作ってみました。
if RUBY_VERSION < '1.9.0' # Ruby1.8でもArray#sampleを使えるようにする class Array def sample n=nil n.nil? ? self[rand(self.size)] : self.sort_by{rand}[0,n] end end end ROW_SIZE = 5 # ビンゴカードの列数 NUMBERS = 1..75 # 出現するナンバーの範囲 STEP = NUMBERS.last / ROW_SIZE CENTER = ROW_SIZE / 2 number_table = [] NUMBERS.step(STEP){|i| number_table << (i..(i - 1 + STEP)).to_a} INIT_CARD = (1..ROW_SIZE).map{Array.new(ROW_SIZE)} # 5列 * 5行の多次元配列を用意 %w(Taro Jiro Hanako Pochi Tama).each do |member| card = INIT_CARD number_table.each_with_index do |line, x| # Array#sampleの出番 line.sample(ROW_SIZE).each_with_index do |num, y| card[y][x] = num if x != CENTER || y != CENTER end end puts "#{member}'s bingo card" card.each do |line| puts ' ' << line.map{|num| (num.nil? ? '*' : num.to_s).rjust(2)}.join(', ') end puts end
実行すると↓こんな感じで出力されました。
Taro's bingo card 1, 23, 45, 50, 73 7, 29, 39, 51, 67 13, 18, *, 52, 72 11, 22, 38, 60, 71 4, 27, 31, 47, 61 Jiro's bingo card 1, 20, 38, 49, 61 12, 29, 36, 60, 65 7, 26, *, 46, 64 9, 24, 43, 48, 74 14, 18, 35, 56, 72 Hanako's bingo card 4, 20, 45, 52, 61 8, 30, 40, 59, 71 14, 17, *, 55, 62 15, 22, 42, 53, 65 9, 29, 32, 56, 67 Pochi's bingo card 15, 22, 43, 58, 68 13, 26, 31, 55, 65 9, 24, *, 59, 69 2, 18, 39, 46, 64 8, 30, 44, 52, 73 Tama's bingo card 6, 16, 43, 53, 62 11, 27, 38, 51, 61 14, 24, *, 54, 73 15, 22, 45, 46, 65 4, 25, 31, 47, 72
なんかグダグダなコードになってしまったけど、とりあえず成功