Snippets
Created by
sironekotoro
last modified
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | #!/usr/bin/env perl;
use strict;
use warnings;
# Perl入学式 2018 in東京 秋開講 第1回 ピザ会でのお題
#
# プレイヤーA, プレイヤーB どちらが勝率が高いか、Perlで解明せよ
# ルール
# プレイヤーA、プレイヤーBに手札が3枚配られる
# 今回は配られる手札は固定とする
# プレイヤーA:1, 5, 10
# プレイヤーB:2, 2, 2
#
# 1 〜 40 の目がランダムにでるルーレットを回し、手札と同じ数字が出たら手札を捨てる
# プレイヤーBのように同じ手札が複数枚ある場合には、同じ目が出ても捨てられるカードは1枚だけ
# 先にカードがなくなった方が勝ち
#
# 追加要素
# Perl入学式(1〜5回)の範囲内の要素だけでやってみる
# リファレンスは使わない
# 試行回数
my $game_count = 1_000_000;
my @player_a = ( 1, 5, 10 );
my @player_b = ( 2, 2, 2 );
# 勝敗結果を格納するハッシュ
my %result;
for my $count ( 1 .. $game_count ) {
# ルーレットを3回まわすサブルーチンから、3つの数を配列で受け取り
# @three_numbers に入る
my @three_numbers = three_times_roulette();
# player_a の手札(1,5,10)と、ルーレットで出た3つの数を配列 @player_a_aggrigate に集める
my @player_a_aggrigate = ( @player_a, @three_numbers );
# player_b の手札(2,2,2)と、ルーレットで出た3つの数を配列 @player_b_aggrigate に集める
my @player_b_aggrigate = ( @player_b, @three_numbers );
# 配列の中の数字の出現回数を調べるサブルーチン number_count に渡し、
# ハッシュを受け取る
my %hash_a = number_count(@player_a_aggrigate);
my %hash_b = number_count(@player_b_aggrigate);
# player_aの勝利条件は以下の2つを満たすこと
# 1.数字の種類が3つ(1,5,10)
# 2.それぞれの出現回数が2回ずつ
if ( keys %hash_a == 3 ) {
# ハッシュのvalueが2の時にカウントするスカラー変数
my $count_value_is_two = 0;
# for文でハッシュの要素1つずつ調べる
for my $num ( keys %hash_a ) {
# ハッシュのvalueが2だったらカウントを加える
if ( $hash_a{$num} == 2 ) {
$count_value_is_two++;
}
}
# カウントが3(ハッシュの3つのkeyに対するvalueがすべて2だった)であれば
# player_a の勝利
if ( $count_value_is_two == 3 ) {
$result{a} += 1;
}
}
# player_bの勝利条件は以下を満たすこと
# 1.数字の種類が1つ(2,2,2)だけ
elsif ( keys %hash_b == 1 ) {
$result{b} += 1;
}
# player_a, player_b どちらでもない場合には引き分け
else {
$result{even} += 1;
}
# プログレスバーの表示
progres_bar($count);
}
# 結果発表
print "player_a が勝った回数:$result{a}\n";
print "player_b が勝った回数:$result{b}\n";
print "引き分けになった回数:$result{even}\n";
# ルーレットを回した結果をスカラー変数で返すサブルーチン
sub roulette {
return int( rand(40) + 1 );
}
# ルーレットを3回した結果を配列で返すサブルーチン
sub three_times_roulette {
my @array;
for my $i ( 1 .. 3 ) {
push @array, roulette();
}
return @array;
}
# 配列の中の数字をkeyに、出現回数をvalueに格納するハッシュを返すサブルーチン
sub number_count {
my @array = @_;
my %hash;
for my $num (@array) {
$hash{$num} += 1;
}
return %hash;
}
# 処理の進捗を示すプログレスバーの処理部
# (なくてもいいけど、あると見栄えする)
sub progres_bar {
my $count = shift;
# 処理結果をためず、すぐに表示するようにするPerlの特殊変数をセット
$| = 1;
# 試行回数に達したら改行する
if ( $count == $game_count ) {
print "\n";
}
# 試行回数が100,000(10万回)ごとに * を表示
elsif ( $count % 100000 == 0 ) {
print '*';
}
# 試行回数が10,000(1万回)ごとに . を表示
elsif ( $count % 10000 == 0 ) {
print '.';
}
}
|
Comments (0)
You can clone a snippet to your computer for local editing. Learn more.