すごろく(第4回Perl入学式@東京)
Perl入学式
2019年7月13日に東京で第4回のPerl入学式が開催されました。
参加者の皆様、講師の@sironekotoro さん、サポーターの皆さんお疲れ様でした。
私はサポーターで参加させてもらいました。
内容
これまでのカリキュラムを多少変えて、第4回はひたすらリファレンスを学びます。
参加者の皆さんの中には、????という方も多かったと思いますが、復習問題を解くなどして、理解していただければなと。
すごろく
例のごとく、終了後のピザ会で@xtetsuji さんに出してもらったお題を当日20分くらいで解いてみました。
問題
- 0から10までのマスがあり、0からスタートし、10に行けばゴールするすごろくがあります。
- 進む距離は1〜6の細工されていないサイコロで決めます。
- ただし、3、6、9のマスに止まった場合、スタートの0に戻されます。
- さて、平均的にサイコロを何回振ればゴールできるでしょうか?
ポイント
サイコロの確率分布
サイコロの1回の試行で出る目の確率分布は離散一様分布になります。
nishiru3.hatenablog.com
乱数の生成
Perlで乱数を生成する事が必要になります。
条件分岐
3、6、9でスタート地点に戻るという条件をif文で再現しています。
期待値の算出
平均的に何回か?という事なので、期待値の算出になります。最終行が期待値になります。
コード
#/usr/bin/env perl use strict; use warnings; use List::Util qw/sum/; # levelが10に達するまでにサイコロを振った回数 my @number_of_trials; for my $i (1..1000000) { # スタート地点は0 my $level=0; # サイコロを振った数を0にする。 my $number_of_trial = 0; # 1回ゴールするまでの繰り返し。 while(1) { # 一様乱数(1 ~ 6) my $number_of_dice = int(rand(6)) + 1; # サイコロを振った数を一つ増やす $number_of_trial++; # サイコロの出た目だけ進める。 $level = $level + $number_of_dice; # levelが3,6,9になったらスタート地点に戻す。 if( $level == 3 || $level == 6 || $level == 9 ) { $level = 0; } # levelが10に達したらゴール if( $level >= 10 ) { # ゴールするのにサイコロを振った回数を配列に記録 push @number_of_trials, $number_of_trial; # ループを抜ける last; } } } # ゴールするのにサイコロを振る回数の期待値 print sum(@number_of_trials)/scalar(@number_of_trials)."\n";