サイコロの度数分布

ふと思いついたので。
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 ■■■