変数、制御構造に続いて重要な概念はプログラムへの入力と出力である。これまで作成したプログラムではプログラムそのものに数値を入れて実行結果を得た。これだけでは全く融通が効かない。
プログラムそのものと、プログラムを実行する際に要する入力、出力結果の三者は区別されるべきものである。
代表的な入力装置は文字入力装置としてのキーボード、出力装置は文字出力装置としての端末である。それぞれ標準入力、標準出力と称する。
input文を使い変数値を標準入力から取得する。引数にはプロンプト文字列をとる。
x=input("x="); printf("%e\n",x);
以下の関係を満たす自然数の組をピタゴラス数と呼ぶ。\[x^2+y^2=z^2\] $x,y,z<n$となるようなピタゴラス数を求めることにする。素朴にプログラムを作成するとプログラム例1のようになる。
clear; n=100; ___ x=_____ ___ y=_____ ___ z=____ __ ( x^2 + y^2 -z^2 == 0 && gcd(x,y) == 1 ) printf( "(%d,%d,%d)\n",x,y,z); endif endfor endfor endfor
アルゴリズムを考えるとプログラム例2のようになる。
clear; n=20; ___ p=[1:ceil(sqrt(n))] ___ q=[1:p] x=_______; y=_______; z=_______; __ ( gcd(x,y)==1 && y < n && z < n ) #if( x < y ) # w=y; # y=x; # x=w; #endif; printf( "(%d,%d,%d)\n",x,y,z ); endif endfor endfor
このプログラムを解読しよう。因数分解すると次のようになる。\[y^2=(z+x)(z-x)\]
$x,y,z$が共通因数を持たないとする。簡単な議論から、$x,z$は奇数、$y$は偶数としてよい。
$x,y$ともに奇数とすれば、$x^2=4n^2+4n+1=4n(n+1)+1$, $y^2=4m(m+1)+1$である。これより、$x^2+y^2 \equiv 2 (\mbox{mod }4)$となる。
一方、$z$が偶数であれば$z^2\equiv 0(\mbox{mod }4)$、奇数であれば$z^2\equiv 1(\mbox{mod }4)$である。これは矛盾。
従って、$x,y$の一方は偶数であり$z$は奇数である。
$z\pm x$はともに偶数であり、次のように変形できる。\[y^2=(z+x)(z-x)=(2U)(2V).\]
$U,V$はそれぞれが$U=p^2$, $V=q^2$という形に書け、$y=2pq$となる。
連立方程式$z+x=2U, z-x=2V$から、$z=U+V=p^2+q^2$, $x=U-V=p^2-q^2$を得る。
clearは定義した変数を全て未定義とする。gcd(x,y)はxとyの最大公約数を返す。
printfは書式付きの出力を与える。第一引数に書式文字列、第二引数以降に変数をとる。書式文字列に%dを与えると変数の値を整数値として出力し、%eを与えると浮動小数点数として出力し、%fを与えると浮動小数点数を小数表示する。複数の%d等が指定された場合、順番に第二引数以降の変数が対応する。
書式文字列中には任意の文字を記述してよい。
octave> x=1.3 x = 1.3000 octave> y=1.4 y = 1.4000 octave> z=1.5 z = 1.5000 octave> printf("(%d, %e, %f)\n",x,y,z); (1, 1.400000e+00, 1.500000) octave> printf("%18d\n",time() ) 1224916194