数列a1=1,an+1=(2+an)^(1/2) に対して、n->∞にしたときのanの極限を計算します。
#!/usr/bin/perl
#
#
# 以下の数列{a_n}の第n項を出力する
# a_1 = 1, a_n+1 = sqrt(2 + a_n) (nは自然数)
#
use feature ':5.16';
use autodie;
my %a; #キャッシュとして第n項の値を保持
say "第n項を表示します。";
for (my $i = 1; $i < 100; $i++) {
say "n = $i","-----a[$i]=",results($i);
}
sub results {
my $n = shift;
# n =1 ならば a_1 =1
if ($n == 1) {
$a{$n} = $n;
return $n;
}
# 第n -1 項の値が存在するなら第n項の値を求める。
if(exists $a{$n - 1}) {
$a{$n} = sqrt(2 + $a{$n - 1});
return $a{$n};
}
}
Memoiseを使って少し書き直しました。
#!/usr/bin/perl
#
#
# 以下の数列{a_n}の第n項を出力する
# a_1 = 1, a_n+1 = sqrt(2 + a_n) (nは自然数)
#
use Modern::Perl;
use autodie;
use Memoize;
memoize('a');
say "第n項を表示します。";
my $start = time();
for (my $i = 1; $i < 10000; $i++) {
say "n = $i","-----a[$i]=",a($i);
}
my $end = time();
if (1) {
say "Programme started: ", scalar localtime($start);
say "Programme ended: ", scalar localtime($end);
}
sub a{
my $n = shift;
# n =1 ならば a_1 =1
if ($n == 1) {
return $n;
}
sqrt(2 + a($n - 1));
}
Memoiseを使った場合の実行結果
Programme started: Wed Feb 13 00:37:19 2013 Programme ended: Wed Feb 13 00:37:20 2013
Memoiseを使わなかった場合の実行結果
Programme started: Wed Feb 13 00:37:51 2013 Programme ended: Wed Feb 13 00:38:22 2013