こんなん?
for id:dasm:20050919#1127092572
無駄が多いビンゴカード抽選プログラム。
ビンゴカードを作り抽選を行って、ビンゴカードと何回目に何回ビンゴしたかを返す。一応モンテカルロ法、無駄にMersenne Twister。
1から15までrandom permutation掛けるの面倒臭かったので、一様分布で強引に代用。本当はどうやってするのか、知らね。
use Strict; use Math::Random::MT qw(srand rand); package main; # print "Sim\n"; srand(1); my $count = 100; my %numbers = (); foreach (1 .. $count){ my $time = $_; my $bingo = new Bingo; # ビンゴカードを出力する場合は以下を適当に弄る # print $_,":bingo:"; # foreach (1 .. 9) { # print $bingo->getnumber($_),","; # } # print ":\n"; # ここでビンゴを行う. my $i = 0; # チェック用フラグ my $j = 0; my $ball = new Bingo; # ボールを出力する場合は以下を適当に弄る # print $_,":balls:"; # foreach (1 .. 15) { # print $ball->getnumber($_),","; # } # print ":\n"; while ($i ==0){ # ボールを取り出してビンゴカードから消す my $curnum = $ball->{$j}; foreach (1 .. 15){ if ($curnum == $bingo->getnumber($_)){ $bingo->setnumber($_,0); } } # 処理 $i = $bingo->check(); $j = $j+1; } my $nu = $j-1; print $nu," count,",$i," bingo"; print "\n"; # 配列の配列とか嫌なので、ハッシュで。 my $curs = $nu.",".$i; if (!$numbers{$curs}){ $numbers{$curs} = 1; } else { $numbers{$curs} = $numbers{$curs}+1; } } foreach (3 .. 15){ my $i = $_; print $i,":"; foreach (1 .. 3){ my $curs = $i.",".$_; print $_,",",$numbers{$curs},","; } print "\n"; } package Bingo; sub new{ my $this = shift; my @nls = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); my @nl = (0); foreach (1 .. 15) { # 強引なrandom permutation。強引過ぎ(わらい # 今まで出てきていない乱数を得たら、それを配列に加える # my $cur = int(rand(15)+1); # while(grep {$_ == $cur} @nl){ # $cur = int(rand(15)+1); # } # push(@nl,$cur); # 修正 # 配列使って、1個ずつランダムに選んで消していく。 my $cur = int(rand(15-$_)+1); # 1 .. $_の乱数を生成 push(@nl,$nls[$cur]); @nls = grep {$_ != $nls[$cur]} @nls; } my $number = { "1" => @nl[1], "2" => @nl[2], "3" => @nl[3], "4" => @nl[4], "5" => @nl[5], "6" => @nl[6], "7" => @nl[7], "8" => @nl[8], "9" => @nl[9], "10" => @nl[10], "11" => @nl[11], "12" => @nl[12], "13" => @nl[13], "14" => @nl[14], "15" => @nl[15]}; bless $number, $this; return $number; } sub getnumber{ $this = shift; return $this->{$_[0]}; } sub setnumber{ $this = shift; $this->{$_[0]} = 0; return $this->{$_[0]}; } sub check{ $this = shift; my $i = 0; # 横方向と縦方向 foreach (0 .. 2){ if ($this->{$_*3+1}==0 && $this->{$_*3+2}==0 && $this->{$_*3+3}==0){ $i = $i+1; } if ($this->{$_+1}==0 && $this->{$_+4}==0 && $this->{$_+7}==0){ $i = $i+1; } } # 斜め if ($this->{1}==0 && $this->{5}==0 && $this->{9}==0){ $i = $i+1; } if ($this->{3}==0 && $this->{5}==0 && $this->{7}==0){ $i = $i+1; } return $i; }