こんなん?

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;
}