• ベストアンサー

割合で表示について

はじめまして。 以下の動物をを指定した割合でランダムに表示しようと思いますが、どのような方法がありますでしょうか。 ゴリラ(割合4) パンダ(割合2) ラッコ(割合3) スズメ(割合1) ウサギ(割合2) rand関数を使って出来そうだったのでやってみたのですが、うまく割合で分ける事が出来ませんでした。 どなたか、何かアドバイスいただけないでしょうか。 よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

どこらへんが難しいかわかりませんが、こういう感じでしょうか? my @animals = ( {'name' => 'gorilla', 'number' => 4}, {'name' => 'panda', 'number' => 2}, {'name' => 'sea otter', 'number' => 3}, {'name' => 'sparrow', 'number' => 1}, {'name' => 'rabbit', 'number' => 2}, ); sub choose_animal { my $num_all_animals = 0; foreach my $elm (@animals) { $num_all_animals += $elm->{'number'}; } my $choice = rand($num_all_animals); foreach my $elm (@animals) { $choice -= $elm->{'number'}; if ($choice < 0) { return $elm->{'name'}; } } } print &choose_animal()."\n"; 簡単に解説しておくと、 perldoc -f randすれば、randのマニュアルが出てきます。 | rand EXPR | rand Returns a random fractional number greater than or equal to 0 | and less than the value of EXPR. (EXPR should be positive.) つまり、10以下の乱数が欲しかったらrand(10)でいいわけですね。これは少数で出てきますが特に整数にする必要はないのでこのまま使います。ちなみに、下記のプログラムはint(rand(10))などして整数に直してもちゃんと動くはずです。 ある割合で物を選びたい場合、rand(選びたい割合の合計)として、if文で分けるのが普通でしょう。 元の問題を説明のために書き換えて、次の割合で表示させることを考えます。 ゴリラ(2) ラッコ(1) 子犬(3) この場合、if文で普通はこういうプログラムを書きます。 $choice = rand(2 + 1 + 3); if (0 <= $choice && $choice < 2) { print "ゴリラ"; } elsif(2 <= $choice && $choice < 2 + 1) { print "ラッコ"; } elsif(2 + 1 <= $choice && $choice < 2 + 1 + 3) { print "子犬"; } これは、全く同じ動作をさせつつこう書き換えられます。 if (0 <= $choice && $choice < 2) { print "ゴリラ"; } else { $choice -= 2; } if (0 <= $choice && $choice < 1) { print "ラッコ"; } else { $choice -= 1; } if (0 <= $choice && $choice < 3) { print "子犬"; } else { $choice -= 3; } そのままforeachで書き換えると、 foreach my $elm (@animals) { if ($choice < $elm->{'ratio'}) { print $elm->{'name'}; break; } $choice -= 3; } のように書けます。 randの引数もforeachを使って計算し、breakさせる代わりにreturnさせると上のようなプログラムになります。

hana43
質問者

お礼

質問内容があいまいな中、丁寧に回答いただきありがとうございます。 私の知識では、ゴリラ、ラッコ、子犬の例での説明が分かりやすく、大変参考になりました。 ありがとうございました。

その他の回答 (2)

  • KURUMITO
  • ベストアンサー率42% (1835/4283)
回答No.3

割合ですからゴリラからウサギまでで10割りになるようにしてください。 そこで次のようにしてはいかがでしょう。 A2セルから下方にゴリラからA6にウサギまでを入力します。 B2セルからB6セルにはその割合を入力します。1割なら1と、全体で10になるようにします。 C1セルには全体で取り扱う動物の個数を入力します。20匹の動物ということなら20と入力します。 C2セルには次の式を入力して下方にドラッグコピーします。 =IF(A2="","",SUM(B$2:B2)*C$1/10) A10セルには次の式を入力して下方にドラッグコピーします。 =IF(ROW(A1)>C$6,"",RAND()) 乱数が表示されます。 B10セルには次の式を入力して下方にドラッグコピーします。 =IF(A10="","",IFERROR(INDEX(A$2:A$6,IF(COUNTIF(C$2:C$6,RANK(A10,A$10:INDIRECT("A"&MATCH(10^10,A:A))))=1,MATCH(RANK(A10,A$10:INDIRECT("A"&MATCH(10^10,A:A))),C$2:C$6,0),MATCH(RANK(A10,A$10:INDIRECT("A"&MATCH(10^10,A:A))),C$2:C$6,1)+1)),A$2)) これでB10セルから下方にはC1セルに設定された動物の全体の個数がB2セルから下方に並べられた割合に基づいた動物の名前がランダムに表示されます。

  • ki073
  • ベストアンサー率77% (491/634)
回答No.2

既にNo.1で書かれていますが、別解です。 @animals=('ゴリラ', 'ゴリラ', 'ゴリラ', 'ゴリラ', 'パンダ', 'パンダ', 'ラッコ', 'ラッコ', 'ラッコ', 'スズメ', 'ウサギ', 'ウサギ'); print $animals[int(rand($#animals+1))]; 普段Perlを使わないので文法的に怪しいかもしれませんが

関連するQ&A

専門家に質問してみよう