ActiveStateからActivePerlが無償配布されています。これを使うといいでしょう。インストール先(perl.exeがおいてあるところ/デフォルトはc:\usr\bin\?)を環境変数PATHに追加しておきましょう。パスが通ったことを確認するには
perl -v
としてThis is perl,...と表示されればOKです。
別にメモ帳でもいいんだぜ。これを書いてる人はMeadowっていうのを使ってるんだぜ。今のところ定番のIDEってのはないみたい。ActiveStateはVisual Perlってのを開発してたらしいんだけど…開発は打ち切られたらしい ""Engineering support for Visual Perl was discontinued as of December 15, 2005. Installation and configuration support is no longer available. とある。 ""訳:Visual Perlの設計サポートは2005年12月15日をもって打ち切られました。インストールと環境設定のサポートはもう利用できません。 他にも窓の杜やVectorでフリーのものはたくさんあるので探してみ。
初心者用課題に載っているものです。
#!perl print "Hello World!";
(注意:#!行は環境依存) をhello.plとして保存し、
perl hello.pl
として実行すると
Hello World!
と表示される。
1: #!perl
perl.exeというperlインタプリタを呼び出すコマンド。お約束。Perlのインストール環境によって異なる。
2: print "Hello World!";"Hello World!"という文字列を出力するための行。printと最初の"の間にはスペースを入れることが多い。行末に;(セミコロン)を忘れずに。Rubyと違って(ブロック末を除き)省略できない。
#!perl $n=100; for($i=2;$i<=sqrt($n);$i++){ if($n%$i==0){ print "n is not a prime number."; exit; } } print "n is a prime number.";
2: $n=100;
「変数nに100を代入する」という意味。右の値を左に代入する。もちろん逆にはできない。100って数字に何かを代入するのは不自然だ。変数名の前には$(ダラー)を、代入文の後ろには;(セミコロン)を忘れないように。
3: for($i=2;$i<=sqrt($n);$i++){
プログラミング初心者の最初の壁であるループ構文。$iは2から√n(より小さい最大の自然数)まで1ずつ増えながら{〜}の中身を実行していく。実行順序はfor(A;B;C){D}に対してABCDBCDBCDBCDBのような感じ。
$i++
ってのは変数$iの値を1増やすためによく使われる。ここでは$i++と書いても++$iと書いても構わない。実際には全く同じではない。
4: if($n%$i==0){
$n%$iは「$nを$iで割った余り」を意味する($n mod $i)。「数値が等しいか否か」を判断するには演算子==を使う(文字列はeqで比較)。=は2つ並べなきゃだめ。1つだと代入文になってしまう。()内が真なら{}内を実行する。偽なら華麗にスルー。
5: print "n is not a prime number.";
割り切れたということは素数じゃないということ。それを表示する。
6: exit;
プログラムそのものを終了する命令。今回はループを抜けた場合は「割り切れなかった」と判断して「素数だ」と表示するように組んだので、割り切れたら即座に「素数じゃない」と判断して終了するようにしなければいけない。
$n = 101; for(2 .. int sqrt $n){ print "$n is not a prime number.\n" and exit unless($n % $_); } print "$n is a prime number.\n";
#!perl $N=100; @prime = (); @zahlen = 2 .. $N # ステップ1 do{ push(@prime,$zahlen[0]); # ステップ2 for($j=$#zahlen;$j>=0;$j--){ # ステップ3(for文全体) if($zahlen[$j]%$prime[$#prime]==0){ splice(@zahlen,$j,1); } } } while ($zahlen[$#zahlen]>$prime[$#prime]**2); # ステップ4判定 foreach $k (@prime){ #以下表示部分 print "$k "; } foreach (@zahlen){ print "$_ "; }
do〜whileを利用した例。エラトステネスの篩-wikipediaに基づいたコーディング。
3: @prime = ();
@primeには8行目でいきなりpush(要素の末尾に追加)するから空配列を用意しておく。
以下説明では$N=100の場合を使っていくことにする。$zahlen[0]=2,$zahlen[1]=3,...,$zahlen[98]=100がそれぞれ代入される。
7: do{ 〜 14| } while ($zahlen[$#zahlen]>$prime[$#prime]**2);
ループ記法の1つ、do〜while文。while(A){B}はABAB...ABAで終わるのに対し、do{B}while(A);はBABA...BAとなるところがポイント(最初のAの有無)。やりたい処理に応じてループ記法を使いわけるといいお( ^ω^)
8: push(@prime,$zahlen[0]);
pushってのは配列の末尾に配列を足すことができる命令だお。足す方は今回のようにスカラーでもいいお。@prime = (2,3,5),$zahlen[0]=7のときにこれが実行されると@prime = (2,3,5,7),$zahlen[0]=7になるお。
ここでは配列要素を削除していくんだけど、前からその処理をやると詰めが発生するから添字の扱いが面倒だお。ここでは簡単のため@zahlenの後ろから見ていくお。
9: for($j=$#zahlen;$j>=0;$j--){
$#zahlenは@zahlenの最後の添字(要素数-1)を指すお。ここから0番目の要素(そしてこれは必ず除かれる)までループしていくお。
9: for $j(reverse 0 .. $#zahlen){
とも書けるお。
10: if($zahlen[$j]%$prime[$#prime]==0){
ステップ2で最後に加えた数は@primeの末尾にいるお。$#primeは@primeの最後の添字だったから、末尾の要素は$prime[$#prime]となるんだお。
11: splice(@zahlen,$j,1);
spliceは配列,削除を始める添字,削除する項数を受け取って削除してくれるんだお。spliceだけでもいくつか書き方があるけど一例だお。今回は割り切れた添字$j項目の1個だけを削除するからこのように書くお。
このステップはwhile文だけどここまで分かっていれば大したことないと思うお。表示の方を説明するお( ^ω^)
15: foreach $k (@prime){
これはC,Ruby,Javaなどにはない記法(だったはず)だお。これは次とほとんど同じだお
for($k=0;$k<=$#prime;$k++){
下のコーディングをしたときのブロック内で$prime[$k]にあたるものが、上のコーディングでは$kとして使えるお。読みやすさを重視するときに便利なループ処理だお。こっちは必ず配列の全要素についてループしようとするから間違って無限ループに落ちることはないお。
for($k=0;$k<=$#prime;$k++){ for $k (0 .. $#prime){ foreach $k (0 .. $#prime){
は同じ動きだお。
18: foreach (@zahlen){
みたいに添字を省略した場合はデフォルトの値の$_にそのループの値が入るお。
19: print "$_ ";
こんな感じ
$n = 100; @prime = (); # 素数リスト @zahlen = (2 .. $n); # 探索リスト do{ push @prime, $zahlen[0]; # ステップ2 @zahlen = grep { $_ % $zahlen[0] } @zahlen; # ステップ3 } while ($zahlen[-1] > $prime[-1]**2); # ステップ4 print "@prime @zahlen\n";
#!perl $YEAR = 2007; if(($YEAR%4==0&&$YEAR%100!=0)||$YEAR%400==0){ print("$YEAR is a leap year."); }else{ print("$YEAR is not a leap year."); }
3: if(($YEAR%4==0&&$YEAR%100!=0)||$YEAR%400==0){
この行が全て。このプログラムの価値はここだけにある。ここにしかない。条件判断1&&条件判断2は両方成り立てば1,成り立たない方があれば0を返す。条件判断1||条件判断2は少なくとも一方が成り立てば1,さもなくば0を返す。何でこれで大丈夫なのか、閏年-wikipediaを見て悩んでくれ。
#!perl @a = ( [ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 7 , 8 , 9 ], [10 ,11 , 12] ); $m = $#a; $n = @{$a[0]}-1; for($i=0;$i<=$m;$i++){ for($j=0;$j<=$n;$j++){ $b[$j][$i] = $a[$i][$j]; } } for($j=0;$j<=$n;$j++){ for($i=0;$i<=$m;$i++){ print "$b[$j][$i] "; } print "\n"; }
二次元配列を使用した例。
モジュールを使用した例。
use Math::Matrix; $a = new Math::Matrix( [ 1, 2, 3], [ 4, 5, 6], [ 7, 8, 9], [ 10, 11, 12] ); $b = $a->transpose; $b->print;
#!perl # X[n+1] = (A*X[n]+B) mod M $A = 997; $B = 1; $M = 2 ** 16; $n = 100; $x[0] = 12345; # 配列@xの要素は整数 1つ1つの乱数は$x[$i]/$Mで得られる $s=0; for($i=0;$i<$n-1;$i++){ $x[$i+1] = (($A*$x[$i]+$B) % $M); } for($i=0;$i<$n;$i++){ $s += $x[$i]/$M; } for($i=0;$i<$n;$i++){ printf ("%0.4f ",$x[$i]/$M); print "\n" if($i%10==9); } print "Average : " . $s/$n;
5: $M = 2 ** 16;
ここでは**演算子を使ったお。2 ** 16は「2の16乗(2×2×…×2=65536)」の意味だお。
13: $s += $x[$i];
これはメジャーなプログラミング言語ではよく見られる略記法。「$sに配列@xの$i番目を加える」操作だから、
$s = $s + $x[$i];
と書いても構わないお( ^ω^) #でもこれ、左右が絶対等しくないからちょっと気持ち悪い式だと書いてる人は思うんだお。
16: printf ("%5.d ",$x[$i*10+$j]);
ここは表示するだけだから大したところではないけど、一応解説を加えるお。printfってのは元々C言語の言葉だお。PerlでもところどころでC言語の文が使えるから、Cプログラマの人はこっちを使っても大丈夫だお。この文の詳細はC言語の項に任せるお。
17: print "\n" if($i%10==9);
見栄えのために10個ごとに改行を入れようと思ったんだお。添字は0から始まるから、$i=9,19,29,...99のときに改行する。これらの数字の特徴は1の位が9⇔10で割ったら9余るということ。こんな風にif文を後ろに書く記法もあるんだお。あんまり使わないけど今回は例だから使ったお。
if($i%10==9){ print "\n"; }
と書くのと同じことだお。
#!perl $n = 3; # $nの平方根を求める $m = 20; # ループ回数 $x0 = 1; # 初期値 @r = (); $r[0] = $x0; for($i = 0; $i < $m ; $i ++ ){ $r[$i+1] = root($r[$i]); } print "$r[$m-1]"; sub root{ my($rn,$rnn); $rn = $_[0]; $rnn = ($rn**2+$n)/(2*$rn); return $rnn; } exit;
7: @r = ();
これは@rという空の配列を用意するお。8行目で初期値をセットしておくお。
10-12: for($i=0;$i<$m;$i++){ $r[$i+1]=root($r[$i]); }
ニュートン法を使って計算する部分は後述のrootっていうサブルーチンに○投げしてあるお。とりあえず考えなくていいお。ニュートン法は数列(現行教育課程で高2)の隣接2項間漸化式を使う方法だお。$i番目が決まったら$i+1番目が決まる、そんなわけで、その規則をrootサブルーチンに書いてあるんだお。今回は$iが$mに近いほど(最大で$m-1)真の値に近づく仕組み。
13: print "$r[$m-1]";
これが計算したなかで一番近い値となる。$n=3,$m=20の場合小数点以下13桁完璧だお( ^ω^)。
15: sub root{
C言語などの「関数」にあたるのがPerlのサブルーチン。多くの場合、何か値を受け取って、それに応じて何らかの値を返却する。受け取ったものは特殊な配列@_に格納されているお。返却するときはreturnに引数を取ればいい。
16: my($rn,$rnn);
変数のネーミングがちょっと気に入らないけど、ここでは$rnはn番目、$rnnはn+1番目の値を入れることにしたお。myってのはその中身がローカル変数(このサブルーチンの中でのみ有効)だということを決める。
17: $rn = $_[0];
$_[0]にはn番目の値が引数として渡されているので、それをとりあえず$rnに格納しておく
18: $rnn = ($rn**2+$n)/(2*$rn);
ここがニュートン法の計算式で、なんでこうなるかは数学を勉強してもらうしかないお。ニュートン法-Wikipediaの(1.1)式を理解すればOKだお( ^ω^)
とりあえず枠だけ作っておくので誰か埋めて><