先週の課題
まずは先週の課題を片付けましょう。
今週の問題
Zeller の公式
Zeller の公式を用いると,年月日から曜日を調べることができる. y を西暦年,m を月,d を日として,
w = y + [y/4] - [y/100] + [y/400] + [2.6*m + 1.6] + d
で整数 w を定義する. この w を 7 で割った余りが曜日となる(0 から 6 が日曜日から土曜日に対応する). ただし,1月と2月は前年の13月と14月とすること (例えば,2001年1月20日の曜日を計算する場合,2000年13月20日として上式に代入する). [x] はガウス記号で x を超えない整数を表す.
Zeller の公式を Fortran プログラムとして書くと次のようになる.
w = y + y/4 - y/100 + y/400 + (13*m+8)/5 + d
ただし,1月と2月の場合の修正を加えた年月日が整数 y, m, d である.
年月日を表す3つの整数 year, month, day を引数とし,曜日に対応する整数を返す関数 zeller(year, month, day) を定義せよ. 1月と2月の場合に,不用意に仮引数を変更しないように気をつけること. 動作検証用に今日の曜日を調べるメインプログラムも作成せよ.
!------------------------------------------------------------ ! Zeller の公式 ! 西暦年月日 (year, month, day) を入力すると日曜日から土曜日に対応する ! 整数 0, 1, ..., 6 を返す.有効範囲は 1583 年から 3999 年(未確認) !------------------------------------------------------------ integer function zeller(year, month, day) implicit none integer, intent(IN) :: year, month, day ! 作業用の変数 integer :: y, m, d, w ! year, month, day を変更しないように作業変数にコピー y = year m = month d = day ! 1, 2 月の場合の修正 if (m == 1 .OR. m == 2) then !***************************************************************** ! この部分を考えましょう !***************************************************************** end if ! Zeller の公式(w を求める) !***************************************************************** ! この部分を考えましょう !***************************************************************** ! w を 7 で割った余りが曜日になる zeller = mod(w, 7) return end function zeller !------------------------------------------------------------ ! 今日の曜日を調べる !------------------------------------------------------------ program test implicit none integer :: zeller write(*,*) zeller(2113, 12, 9) stop end program test
Zeller の公式 (2)
西暦2000年から2999年の1000年間に13日の金曜日は何回あるか.
覆面算
次の覆面算の解を求めるプログラムを作成し,実際に解を求めよ.
KYOTO +) OSAKA ──────── TOKYO
ただし,解は次の条件を満たすものであること.
- 同じ文字には同じ数字が入り,違う文字には違う数字が入る.
- 最上位の数字は 0 ではない.
ヒント: 文字ごとに do ループを回せばよい. 異なる文字に同じ数字が入っている場合は cycle 文でループをスキップする. cycle 文が実行されると処理がその do ループの最後に移動し,結果的にループの次の繰り返しに移る.