jug7.com
[ home / cgi / juggler / column / diary / bbs / link / welcome ]


source : 継続率による期待値


#!/usr/bin/perl
# 継続率による期待値

$cginame = 'ren.cgi'; 
$title   = '継続率による期待値';

print "Content-Type: text/html\n\n";

if ($ENV{'REQUEST_METHOD'} eq 'POST') {
    read (STDIN, $input, $ENV{'CONTENT_LENGTH'});
}
$input =~ s/ren=//;

# ヘッダとフォームの表示
print <<"__ HTML __";
<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>
<html lang='ja'>
<head>
<meta http-equiv='Content-Type' content="text/html; charset=shift_jis">
<title>jug7.com - cgi $title</title>
 <style type="text/css"> <!--
   A:hover {color:#ff0000;}
 --></style>
</head>
<body text='#000000' bgcolor='#ffffff' link='#0000ff' alink='#ff0000' vlink='#0000cc'>
<div align='right'>[ <a href='ren_memo.html'>memo</a> / <a href='ren.html'>source</a> / <a href='../index.html'>home</a> ]</div>
<br><br>
<div align='center'><h2>$title</h2></div>
<hr width='70%'><center>
<form action='$cginame' method='POST'>
継続率 <input type='text' size=7 maxlength=6 name='ren' value='$input'> %<br><br>
<input type='submit' value="開始"><br>
</form>

<table border=0 align='center' width='50%'>
継続率に0〜96以外の数値を入力すると1000回シミュは行われません。
小数点も記入できます。</td></tr></table><br><br><br>
</center>
__ HTML __


# エラーチェックと GET送信
if (!$input) { $error = 1; $er_msg = '記入漏れがあります。'; }
if ($input >= 100) { $error = 1; $er_msg = '継続率は 100 未満の数値です。'; }
if ($input =~ /[^\d\.]/) { $error = 1; $er_msg = '不適切な文字が記入されています。'; }
if ($ENV{'REQUEST_METHOD'} ne 'POST') { $error = 1; $er_msg = 0; }
if ($er_msg) {
    print q{<center><b><font color='red' size=4>*** ERROR !! ***</font><br><br>},"\n";
    print "$er_msg</b></center>\n";
}
if ($error) {
    print '<br><br><br><br><br>';
    print q{<div align='right'>[ <a href='ren_memo.html'>memo</a> / <a href='ren.html'>source</a> / <a href='../index.html'>home</a> ]</div>};
    exit;
}

#--------------------
#   計算,シミュ開始
#--------------------
$calc = 1/(1-$input/100);
$calc = &point($calc, 3);  # 四捨五入。小数点第3位まで表示

print <<"__ HTML __";
<br><blockquote>
<font color='#00aa00'>■</font> <b>計算結果</b><br>
<blockquote>
無限等比級数の公式 <b>1/(1-r)</b> を用いた計算結果<br><br>
継続率 <b>$input %</b> による期待値 <font color='red'><b>$calc 回</b></font><br>
</blockquote></blockquote>
__ HTML __

# シミュレート ( 1000回 & 30回 )
if ($input<96) {

    # 1000回 シミュレート
    $input2 = $input * 1000;
    for (1..1000) {
        while(1) {
            $r = int(rand(100000)+1);
            if ($r <= $input2) { $ren++; next; }
            else { $t_ren += $ren + 1;  $ren = 0; last; }
        }
    }
    $ave_ren = &point(($t_ren/1000), 3); # 平均連荘数

    print q{<br><blockquote><font color='#00aa00'>■</font> <b>1000回試行のシミュレーション結果</b><br>},"\n";
    print "<blockquote>継続率 <b>$input %</b> による期待値";
    print " <font color='red'><b>$ave_ren 回</b></font><br>\n</blockquote></blockquote>\n";
    print q{<br><blockquote><font color='#00aa00'>■</font> <b>30回試行(シミュ)の例</b><br><br>},"\n";


    # 30回シミュレート
    $ren = $t_ren = 0;
    $input2 = $input * 1000;
    for (1..30) {
        while(1) {
            $r = int(rand(100000)+1);
            if ($r <= $input2) { $ren++; next; }
            else {
                $ren++; push(@simu30, $ren);
                $ren = 0; last;
            } 
        }
    }

    # 30回シミュ結果の表示
    print '<blockquote><table border=0><caption><font size=2>30回試行の例</font></caption><tr>',"\n";

    $x = 0; $y = 0; $z = 1;
    while($x <= 2) {
        print q{<td> <table border=1 align='center' cellspacing=0 cellpadding=3>},"\n";
        print q{<tr align='right' bgcolor='#ffffcc'><td> </td><td><font size=2>継続<br>回数</td></tr>},"\n";

        for ($y=$z; $y<$z+10; $y++) {
            $ren_d = ($simu30[$y-1]==1) ? '単発' : "<font color='blue'>$simu30[$y-1] 連</font>";
            print "<tr align='right'><td><font size=2>$y</font></td><td>$ren_d</td></tr>\n";
            $t30_ren += $simu30[$y-1];
        }
        print '</table></td><td>',"\n";
        $x++; $z += 10;
    }
    print '</td></tr></table>',"\n";
    $ave_ren = &point(($t30_ren/30), 3);
    print "<br>平均 $ave_ren 連<br><br></blockquote>\n";

} else {
    print <<"    __ ERROR __";
    <br><blockquote>
    <font color='#00aa00'>■</font> <b>20000回試行のシミュレーション結果</b><br>
    <blockquote><font color='red'><b>ERROR!</b></font><br><br>
    入力された数値が大きすぎるため、1000回試行シミュは行いませんでした。
    </blockquote></blockquote>
    <br><blockquote>\n<font color='#00aa00'>■</font> <b>30回試行(シミュ)の例</b><br>
    <blockquote><font color='red'><b>ERROR!</b></font><br><br>
    入力された数値が大きすぎるため、30回試行シミュは行いませんでした。
    </blockquote>
    __ ERROR __
}


# 再試行ボタンとフッタ
print <<"__ HTML __";
</blockquote>
<form action='$cginame' method='POST'>
<input type='hidden' name='ren' value='$input'>
<blockquote><input type='submit' value="再試行">
</blockquote></form><br><br>

<div align='right'>[ <a href='ren_memo.html'>memo</a> / <a href='ren.html'>source</a> / <a href='../index.html'>home</a> ]</div>
</body></html>
__ HTML __

exit;

# 少数を四捨五入して指定の桁にする
sub point {
    my($value, $fig, $x);
    ($value, $fig) = @_;

    $value = int($value * (10 ** $fig) + 0.5) / (10 ** $fig);
    if ($value =~ /(\d+)\.(\d+)/) { $x = $2; }
    elsif ($value !~ /\./)        { $x =''; $value .= '.'; }
    $value = $value.'0' x ( $fig - length($x) );
    return $value;
}


[ home / cgi / juggler / column / diary / bbs / link / welcome ]