前回2 でも 3 でも割れないと真を返し,それ以外は偽を返す関数 f1_3 は以下のように書いた.
sub f1_3 { my ($number) = @_; my $result = 1; if ($number % 2 == 0){ $result = 0; } if ($number % 3 == 0){ $result = 0; } return $result; }
図2.1 関数 f1_3
5 で割るテストを付け加えて 2 でも 3 でも 5 でも割れない数 かどうかを判定する関数を作ることができるが,これを進めて, number - 1 まで割って割れなければ素数,どこかで割れれば素数で ない,という論理で素朴な素数判定ルーチンを作ることができる. ただし,number の値は実行時に変わるのでプログラム作成時に 何行書けばいいのかが確定しない.この問題はループを使うことで 解決できる.ループ変数 i を導入して 以下の文をループで i = 2 から number - 1 まで実行すればよい.
if ($number % $i == 0){ $result = 0; }
図2.2
図2.2を適切なループに入れて素数であれば 1, そうでなければ 0を変える関数 prime を作り, 2 から順に 10 までの整数を prime に入力として 与えた返り値を出力するプログラム ex2_1.pl を作れ.
2 から順に 100 までの整数を prime に入力として与えたとき, 返り値が 1 になるものだけについて prime への入力の値を出力するプログラム ex2_2.pl を作れ.
キーボードから入力を行い,入力された値以下の 素数を小さいものから順に出力するプログラム pime.pl を作製せよ.
動作確認はあらかじめ正しい素数を出力した以下のリンクのファイル を用いて行う.右クリックから保存する場所をホーム直下の pl ディレクトリに指定して保存せよ.
例えば,上の 10000以下の素数の出力を prime10000.txt というファイル名で 保存しておく.以下のコマンドで自分が作成したプログラムの出力を ファイルに出力する.(リダイレクション)
jt00000a@yamamoto-00:~/pl$ ./prime.pl > out.txt
図2.3
2 つのファイルの内容の違いを調べるには diff を使用する.
jt00000a@yamamoto-00:~/pl$ diff prime10000.txt out.txt
図2.4
2つのファイルの内容が全く同じなら何も出力されない. 違いがあればその行だけが出力される.out.txt のどこか 1行を書き換えて diff を実行してみよ.
10000以下の素数 が一致することを確認できたら動作確認を行う.
time 関数を使うことでシステムの現在時刻を得ることができる. これを利用して実行時間を測定することができる.方法は prime.pl のメインルーチンの for ループの前と後を 以下のように変更する.
$stime = time; for ($n = 2; $n <= 100000; $n++){ if (&prime($n) == 1) { print "$n\n"; } } $etime = time; $ptime = $etime - $stime; print "Time: $ptime\n";
図2.5
ただし,新しい変数 $stime, $etime, $ptime を導入したので プログラム最初の my $n; の部分を以下の様に変更しなければ ならない.(use strict を指定しているため)
my $n; my $stime; my $etime; my $ptime;
図2.6
最初の $stime = time で処理開始の時刻を変数 $stime に保存し, 終了の時刻を変数 $etime に保存している.両変数の差を 求めることで処理にかかった秒数を知ることができる. ループ回数を変更して処理時間の変化を確認せよ
prime 関数だけを変更し,高速化を試みよ. (高速化をアルゴリズムの工夫で行う.手法は自分調べ,考える) 変更後のプログラムの出力を diff で正解ファイルと比較し 正しいことを確認せよ.処理時間の変化も確認せよ.
prime.plを 添付メールとして提出せよ.
動作確認で行った作業とその結果を メールの本文内で報告せよ.
メールの宛先は <hiroshi@tokai.ac.jp> とし, Subject (件名)を Seminar 2-1 とせよ.