ユーザーが当てるプログラムは完成しました。
次は、コンピュータに当てさせることを考えてみましょう。
候補数リストを使って質問を選択させることを考えます。
個数が最大である分類が質問の回数に影響すると考え、候補数リストの最大値で評価します。ただし、質問が候補リストにある場合には、値に-1の修正を行います。
候補数リストの回数だけ繰り返し、最大値を求めます。
評価@サブルーチン
# 評価@サブルーチン sub hyoka1 { my @kouhosu=@_; # 候補数リストを受け取る my $i; my $max=0; # 最大値を0に初期化 for ($i=0; $i<=12; $i++) { # 候補数リストの個数分繰り返し if ($kouhosu[$i]>$max) { # 現在の最大値を越えたら最大値を更新 $max=$kouhosu[$i]; } } if ($kouhosu[12]==1) { # 候補リストに含まれる場合 $max=$max-1; } return $max; }
個数nの候補リストから答えを見つけるのに必要な質問の回数は、log(n)に比例すると考え、n*log(n)の総和で評価します。ただし、質問が候補リストにある場合には、値に-2*log2の修正を行います。
候補数リストの回数だけ繰り返し、n*log(n)の値を加算していきます。
評価Aサブルーチン
# 評価Aサブルーチン sub hyoka2 { my @kouhosu=@_; # 候補数リストを受け取る my $i; my $sum=0; # 合計値を0に初期化 for ($i=0; $i<=12; $i++) { # 候補数リストの個数分繰り返し if ($kouhosu[$i]!=0) { # 0のlogは取れないので0の場合には処理を飛ばす $sum=$sum+$kouhosu[$i]*log($kouhosu[$i]); } } if ($kouhosu[12]==1) { # 候補リストに含まれる場合 $sum=$sum-2*log(2); } return $sum; }
すべての質問に関して評価を行い、最も評価値の低くなる質問を返すサブルーチンを作成します。
質問の選択サブルーチン
# 質問の選択サブルーチン sub select_question { my @kouho=@_; # 候補リストを受け取る my $min=10000; # 最小値を10000に初期化 my @kouhosu; my @question; foreach $question (@allkouho) { # すべての質問について繰り返し @kouhosu=&count_kouho($question, @kouho); # 質問で候補を分類 $hyoka=&hyoka2(@kouhosu); # 評価A if ($hyoka<$min) { # 現在の最小値を下回ったら最小値とその質問を更新 $min=$hyoka; $min_question=$question; } } return $min_question; }メインルーチンの修正
ユーザーからの入力部分をコメントアウトして、質問の選択サブルーチンを呼ぶように変更します。
#$number=&input; # 入力 $number=&select_question(@kouho); # 質問の選択サブルーチン