Powered by SmartDoc

コンピュータ

第4回
北海道大学理学部数学科

入出力

変数、制御構造に続いて重要な概念はプログラムへの入力と出力である。これまで作成したプログラムではプログラムそのものに数値を入れて実行結果を得た。これだけでは全く融通が効かない。

プログラムそのものと、プログラムを実行する際に要する入力、出力結果の三者は区別されるべきものである。

代表的な入力装置は文字入力装置としてのキーボード、出力装置は文字出力装置としての端末である。それぞれ標準入力、標準出力と称する。

パラメータを標準入力から取得

input文を使い変数値を標準入力から取得する。引数にはプロンプト文字列をとる。

x=input("x=");
printf("%e\n",x);

ピタゴラス数

以下の関係を満たす自然数の組をピタゴラス数と呼ぶ。\[x^2+y^2=z^2\] $x,y,z<n$となるようなピタゴラス数を求めることにする。素朴にプログラムを作成するとプログラム例1のようになる。

プログラム例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のようになる。

プログラム例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

課題

  1. 第1の例を実行する。
  2. 第2の例について、nを変更して実行できるように変更して実行する。input文を使う。