Numerical sequence

home

Numerical sequence

数列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