この文書の URL は http://www.cc.kyoto-su.ac.jp/~mtkg/lecture/comp_B/2012/report1.html です。
前半のまとめの問題
問1. Zeller の公式
Zeller の公式を利用して西暦2112年9月3日の曜日を求めよ。 西暦年月日 (year, month, day) を引数とする関数 zeller(year, month, day) を定義し、それを使うこと。
問2. 覆面算
次の覆面算の解を求めるプログラムを作成し、実際に解を求めよ。
KYOTO +) OSAKA ──────── TOKYO
ただし、解は次の条件を満たすものであること。
- 同じ文字には同じ数字が入り、違う文字には違う数字が入る。
- 最上位の数字は 0 ではない。
ヒント: 文字ごとに do ループを回せばよい。 異なる文字に同じ数字が入っている場合は cycle 文でループをスキップする。 cycle 文が実行されると処理がその do ループの最後に移動し、結果的にループの次の繰り返しに移る。
! cycle 文の例 -- 奇数だけ画面に表示する do ループ do i = 1, 10 if (mod(i, 2) == 0) cycle ! i が偶数の場合は以下をスキップし、次の i に移る。 write(*,*) i end do
問3. ルジャンドル多項式
ルジャンドル多項式 Pn(x) は |x| <= 1
を満たす x に対して次の漸化式で定義される。
P0(x) = 1 P1(x) = x Pn(x) = [(2*n-1) * x * Pn-1(x) - (n-1) * Pn-2(x)] / n (n = 2, 3, ...)
P5(x) の値を -1
から 1
までの x について 0.1 刻みで求め、
Gnuplot でグラフをプロットせよ。
任意の n と x についてルジャンドル多項式 Pn(x) の値を返す関数 lp(n, x) を定義し、それを用いること。
問4. 多数桁計算
「整数÷整数」の計算を小数の任意の桁まで行うプログラムを作成せよ。 2つの整数 a, b と桁数 n はキーボードから入力する。 ただし、桁数の上限はあらかじめ決めておいてよい(以下のヒントでは 1000 としている)。
ヒント: 筆算をプログラムに直せばよい。 商の整数部を表す整数 p と小数部を表す整数配列 q(:) を用意し、筆算をループで表現する。
! nmax 桁数の最大 ! p 商の整数部 ! q(i) 商の小数部, q(i) は商の小数第 i 桁を表す program main implicit none integer, parameter :: nmax = 1000 integer :: p, q(nmax) integer :: a, b, n : ! 結果の表示 write(*,*) p write(*,'(5(X,10I1))') q(1:n) stop end program main
問5. 測地線
地球上の2地点の緯度・経度から2地点間の(大円に沿った)最短距離を求めるプログラムを作成し、京都−ローマ間の距離を求めよ。 大円とは球と球の中心を含む平面との交線のことである。 地球は回転楕円体ではなく半径 6370 km の球であるとしてよい。 京都とローマの緯度・経度は次の値を用いること。
京都 北緯35度00分30秒 東経135度46分16秒 ローマ 北緯41度53分35秒 東経 12度28分60秒
ヒント: 球上の異なる2点を A, B、球の中心を O とする。 角 AOB のなす角がわかれば AB 間の最短距離(弧 AB の長さ)が計算できる。 角 AOB のなす角は OA ベクトルと OB ベクトルの内積から求められる(cos の逆関数 acos を利用せよ)。 OA ベクトルと OB ベクトルの内積は A と B の座標がわかれば計算可能である。 半径 r の球面中の緯度θ・経度φにある点の座標 (x, y, z) は r, θ, φ を使って次のように表される。
x = r cosθ cosφ y = r cosθ sinφ z = r sinθ
問6. 多数桁計算(Napier 数)
自然対数の底 e (Napier 数)を任意の桁数(小数第 K 位)まで計算するプログラムを作成せよ。 Napier 数の求め方は以下の通り(京大冨田先生の解説より)。
e = 1 + 1/1! + 1/2! + 1/3! + 1/4! + ... [exp(x) の x=1 でのテイラー展開]
を次のように変形する。
1 1 1 1 1 e = 1 + - (1 + - (1 + - (1 + ... --- (1 + -) ...))) 1 2 3 M-1 M
小数第 K 位までの多数桁小数を考え、「多数桁小数÷整数」の計算を次のように繰り返す。
- 十分大きな整数 M に対して 1.000…0 / M を計算し、1 を加える。(最初の多数桁小数は整数部が 1、小数部がすべて 0 とする。)
- その結果を M-1 で割り、1 を加える。
- その結果を M-2 で割り、1 を加える。
- …
- その結果を 1 で割り、1 を加える。
このようにして任意の精度で e が求められる。 小数第 K 位まで求める場合、M は M > K*log(10.0) であれば十分である。 例えば K=100 桁の計算をするには K*log(10.0) = 230.25… より M=231 とすればよい。