サイコロの度数分布
ふと思いついたので。
n面体サイコロをm個振って出目を合計する場合、どの結果がどのくらいの確率で出るか、結果の分布度数を高速に計算できないかと思って作った品。
use strict; use List::Util qw ( sum max ); my $aspect = 6; # サイコロの面の数 my $num = 2; # サイコロの数 my @number = (); foreach my $i ( 1..$num ) { # 最初の一周 if ( 0 == scalar @number ) { map { $number[$_] = 1 } ( 1..$aspect ); next; } # 二週目以降 my @new = (); foreach my $m ( 0..scalar @number ) { $number[$m] or next; foreach my $l ( 1..$aspect ) { $new[$m+$l] += $number[$m]; } } @number = @new; } my $sum = sum @number; my $max = max @number; foreach my $i ( 0..scalar @number ) { $number[$i] or next; printf "%3d : %10d/", $i, $number[$i]; print "$sum "; print '■' x (20*$number[$i]/$max); print "\n"; }
もっとアルゴリズム的に贅肉を落とせそうな気はするんだが……。
実行例
2 : 1/36 ■■■ 3 : 2/36 ■■■■■■ 4 : 3/36 ■■■■■■■■■■ 5 : 4/36 ■■■■■■■■■■■■■ 6 : 5/36 ■■■■■■■■■■■■■■■■ 7 : 6/36 ■■■■■■■■■■■■■■■■■■■■ 8 : 5/36 ■■■■■■■■■■■■■■■■ 9 : 4/36 ■■■■■■■■■■■■■ 10 : 3/36 ■■■■■■■■■■ 11 : 2/36 ■■■■■■ 12 : 1/36 ■■■