sironekotoroの日記

Perl で楽をしたい

Software Design 2017年12月号

うわ、ずいぶんとblog書いてなかった・・・

最近、ドワンゴN予備校に入学しました。

www.nnn.ed.nico

とあるJavaScript本で勉強していたんですが、本の内容と付録CDROMでコードが異なるとか、コードの追加部分が分かりにくい等でめっちゃストレスが溜まっていたんですね。 一度、有料のオンライン講座?講義?的なものに挑戦したかったのと、増田で話題になっていたこともあり、興味本位での入学です。

anond.hatelabo.jp

ところが、ログイン後の初期画面に表示されていた「数学I」をちょっと覗き見し、その問題にちょっと手を出したところ、解けない・・・かつては解けた、二次関数のグラフが書けない・・・もう、超ショックを受け、一念発起、中学数学から復習してる昨今です。

平方根の付け外し、移項に伴う符号(+-)の逆転、指数計算とそれまでの学習全部を使って導く「解の公式」。 中学数学の中ボス感すごい。

{ \displaystyle
x = \frac{-b\pm \sqrt{b^{2}-4ac}}{2a}
}

で、タイムリーなことにSoftware Design 2017年12月号の特集は「ITエンジニアと数学」。

gihyo.jp

生きていると、たまに自分の欲しいものがタイミングよく現れることがあるんですが、今回もそう。 早速、最初に載っていた「モンティ・ホール」問題のスクリプトPerlで書いてみました。 元はPythonで書かれているのですが、構造や単語からなんとなく読めるのがプログラムのいいところですね。

use strict;
use warnings;

sub game {
    my $change_door = shift;

    my $prize  = int( rand(3) );    # 正解 0,1,2 のどれか
    my $choice = int( rand(3) );    # 最初の選択 0,1,2 のどれか

    my $open_door;   # モンティが開くドアの選択 0,1,2 のどれか

    while (1)
    { # モンティが選ぶドアが$pize,$choiceと重ならないようにループを回す
        $open_door = int( rand(3) );

        # 重ならない値が決まったらループを抜ける
        last if ( $open_door != $choice and $open_door != $prize );
    }

    if ($change_door) {    # 選択を変更する場合
           # ドアは0,1,2しかないので、数の決まったforを使う
        for ( my $new_choice = 0; $new_choice < 3; $new_choice++ ) {

            # 選択し直したドアは、最初にに選んだドア、
            # モンティが開けたドアと重ならないようにする
            if ( $new_choice != $choice and $new_choice != $open_door ) {
                # 条件に合致したら、新たに選択したドアの情報を$choiceに設定して抜ける
                $choice = $new_choice;
                last;
            }
        }
    }

    # 選択したドアが商品が入っていたドアなら1点
    if ( $choice == $prize ) {
        return 1;
    }
    # 外れてたら0点
    else {
        return 0;
    }
}

sub play {
    my ( $num, $change_door ) = @_;
    my $point = 0;

    for ( my $i = 0; $i < $num; $i++ ) {
        $point += game($change_door);
    }
    return $point;
}

my $num = 10000; # 試行回数

my $score = play( $num, 0 );
print "変更しない場合の勝率\t", $score / $num, "\n";

$score = play( $num, 1 );
print "変更した場合の勝率\t", $score / $num, "\n";

うちの結果はこんな感じでした。なるほど。

変更しない場合の勝率  0.3254
変更した場合の勝率   0.658

あと、「課外授業4 数学の勉強法」にあった

確実にわかる、自信が持てるところから再出発しましょう。高校レベル、あるいは中学レベルまで戻って勉強しなおしてみましょう。
(中略)
ノートとボールペンをどれだけ消費するか

これはうちの勉強方針とも合致してて、間違った方向にいってなさそう!と心強く思いましたわ。引き続き頑張りまする。