このディレクトリの索引
#  [1] 授業単元:著作権 
#  [2] 問題文(含コード&リンク): 
#  
#  標準入力から西暦(グレゴリオ暦)を受け取り、 
#  その年のイースターの日を計算するプログラムを作成してください。
#  結果の表示はしてもしなくてもかまいません。 
#  
#  [3] 環境 
#   [3.1] OS: (Windows/Linux/等々) 
#   [3.2] コンパイラ名とバージョン: (gcc 3.4 VC 6.0等) 
#   [3.3] 言語: (C/C++/どちらでも可 のいずれか) 
#  [4] 期限: ([yyyy年mm月dd日hh:mmまで] または [無期限] のいずれか) 
#  
#  [5] その他の制限: (どこまで習っているか、標準ライブラリは使ってはいけない等々) #  
#  
#  イースターの日の決め方
#  
#  イースターの日の決め方の単純な定義は「春分の日の次の満月の後の最初の日曜日」ということになります。
#  尚、その満月の日が日曜日の場合は翌日曜日がイースターとなります。
#  
#  しかしながら、厳密に申しますとこの定義は正しくありません。
#  まず、ここでいう「春分の日」は天文学的な意味での春分の日ではなく常に3月21日とします。
#  「満月の日」というのも天文学的な意味での満月の日ではなくMetonic cycleという周期に基づいたものなのです。
#  
#  この理由は、地球上の経度の違い、即ちタイムゾーンの違いによって地域によってイースターの日が変ってしまうという混乱を防ぐためなのです。
#  イースターの日を決めるということはそもそも礼拝式典の必要から生じてきました。
#  8世紀までは決め方に関する定まった方法はありませんでしたが、
#  AD325年のニカヤ会議による方法が徐々に取り入れられていったようです。
#  グレゴリオ暦の採択によって幾分かの修正が必要となりましたが基本的には同じです。
#  
#  逆に言うと、Metonic cycleさえ知っていれば、将来のイースターの日を計算することが可能なのです。
#  
#  試してみたい方は、次のようなアルゴリズムによって1900年から2099年までのイースターの日が計算できます。
#  
#  1.まず調べたい年の西暦年を19で割った余りを計算します。
#  
#  (例えば2006年の場合は19で割って余りが11)
#  
#  2.その余りに11をかけて225から引いた数字をDとします。
#  
#  (D=225-11×11= 104)
#  
#  3.もしDが51以上の時は51未満になるまで30で引き、改めてそれをDとします。
#  
#  (D=104-30-30=44)
#  
#  4.もし、Dが48よりも大きい時はそれから1を引きます。
#  
#  (D=44なのでそのまま)
#  
#  5.西暦年と、西暦年を4で割った数字(小数点以下切り捨て)と、D+1とを足し、それを7で割った余りをEとします。
#  
#  (2006+501+44+1=2552となり7で割ると余りが4なのでE=4)
#  
#  6.Dに7を足してEで引き、それをQとします。
#  
#  (Q=44+7-4=47)
#  
#  7.もし、Qが31以下の時はイースターは3月でその数字がイースター日付を表わします。Qが32以上の場合はイースターは4月でQから31を引いた数字が日付を表わします。
#  
#  (Qは47なので、イースターは4月そして日付は47-31=16日)
#  
#  堺福音教会東京チャペル 
#  tokyo@jec-net.org 
#  TEL.03-3642-5242/FAX.03-3642-5479 
#  〒135-0042 東京都江東区木場2丁目17-10-301 
#  のサイトからの引用



'イースターの日の決め方

イースターの日の決め方の単純な定義は「春分の日の次の満月の後の最初の日曜日」ということになります。
尚、その満月の日が日曜日の場合は翌日曜日がイースターとなります。

しかしながら、厳密に申しますとこの定義は正しくありません。
まず、ここでいう「春分の日」は天文学的な意味での春分の日ではなく常に3月21日とします。
「満月の日」というのも天文学的な意味での満月の日ではなくMetonic cycleという周期に基づいたものなのです。

この理由は、地球上の経度の違い、即ちタイムゾーンの違いによって地域によって
イースターの日が変ってしまうという混乱を防ぐためなのです。
イースターの日を決めるということはそもそも礼拝式典の必要から生じてきました。
8世紀までは決め方に関する定まった方法はありませんでしたが、
AD325年のニカヤ会議による方法が徐々に取り入れられていったようです。
グレゴリオ暦の採択によって幾分かの修正が必要となりましたが基本的には同じです。
試してみたい方は、次のようなアルゴリズムによって1900年から2099年までのイースターの日が計算できます。

1.まず調べたい年の西暦年を19で割った余りを計算します。

(例えば2006年の場合は19で割って余りが11)

2.その余りに11をかけて225から引いた数字をDとします。

(D=225-11×11= 104)

3.もしDが51以上の時は51未満になるまで30で引き、改めてそれをDとします。

(D=104-30-30=44)

4.もし、Dが48よりも大きい時はそれから1を引きます。

(D=44なのでそのまま)

5.西暦年と、西暦年を4で割った数字(小数点以下切り捨て)と、D+1とを足し、それを7で割った余りをEとします。

(2006+501+44+1=2552となり7で割ると余りが4なのでE=4)

6.Dに7を足してEで引き、それをQとします。

(Q=44+7-4=47)

7.もし、Qが31以下の時はイースターは3月でその数字がイースター日付を表わします。Qが32以上の場合はイースターは4月でQから31を引いた数字が日付を表わします。

(Qは47なので、イースターは4月そして日付は47-31=16日)' :-

        堺福音教会東京チャペルのサイトからの引用.



'標準入力から西暦(グレゴリオ暦)を受け取り、
その年のイースターの日を計算するプログラムを作成してください。
結果の表示はしてもしなくてもかまいません。'(_西暦,_月,_日) :- 
        '標準入力から西暦(グレゴリオ暦)を受け取り、'(_西暦),
        'Metonic cycleを使ってその年のイースターの日を計算する'(_西暦,_月,_日).

'標準入力から西暦(グレゴリオ暦)を受け取り、'(_西暦) :-
        整数を得る('西暦(グレゴリオ暦)',グレゴリオ歴(_西暦),_西暦).

'Metonic cycleを使ってその年のイースターの日を計算する'(_西暦,_月,_日) :-
        'まず調べたい年の西暦年を19で割った余りを計算します。その余りに11をかけて225から引いた数字をDとします。'(_西暦,D),
        'もしDが51以上の時は51未満になるまで30で引き、それをD_2とします。もし、Dが48よりも大きい時はそれから1を引きます。'(D,D_2),
        '西暦年と、西暦年を4で割った数字(小数点以下切り捨て)と、D_2 + 1 とを足し、それを7で割った余りをEとします。'(_西暦,D_2,E),
        'D_2に7を足してEで引き、それをQとします。'(D_2,E,Q),
        'もし、Qが31以下の時はイースターは3月でその数字がイースター日付を表わします。Qが32以上の場合はイースターは4月でQから31を引いた数字が日付を表わします。'(Q,_月,_日).

'まず調べたい年の西暦年を19で割った余りを計算します。その余りに11をかけて225から引いた数字をDとします。'(_西暦,D) :-
        _19で割った余り is _西暦 mod 19,
        D is 255 - _19で割った余り * 11.

'もしDが51以上の時は51未満になるまで30で引き、それをD_2とします。もし、Dが48よりも大きい時はそれから1を引きます。'(D,D_2) :-
        'もしDが51以上の時は'(D),
        '51未満になるまで30で引き、それをD_2とします。'(D,D_2).
'もしDが51以上の時は51未満になるまで30で引き、それをD_2とします。もし、Dが48よりも大きい時はそれから1を引きます。'(D,D_2) :-
        'もし、Dが48よりも大きい時は'(D),        
        'それから1を引きます。'(D,D_2).

'もしDが51以上の時は'(D,D_2) :-
        D >= 51.

'51未満になるまで30で引き、それをD_2とします。'(D,D_2) :-
        D_2 is ((D - 51) // 30) + 1) * 30.

'もし、Dが48よりも大きい時は'(D) :-
        between(48,50,D).

'それから1を引きます。'(D,D_2) :-
        D_2 is D - 1.

'西暦年と、西暦年を4で割った数字(小数点以下切り捨て)と、D_2 + 1 とを足し、それを7で割った余りをEとします。'(_西暦,D_2,E) :-
        _西暦年を4で割った数字 is _西暦 // 4,
        E is (_西暦年を4で割った数字 + D_2 + 1) mod 7.

'D_2に7を足してEで引き、それをQとします。'(D_2,E,Q) :-
        Q is D_2 + 7 - E.

'もし、Qが31以下の時はイースターは3月でその数字がイースター日付を表わします。Qが32以上の場合はイースターは4月でQから31を引いた数字が日付を表わします。'(Q,3,Q) :-
        Q =< 31,!.
'もし、Qが31以下の時はイースターは3月でその数字がイースター日付を表わします。Qが32以上の場合はイースターは4月でQから31を引いた数字が日付を表わします。'(Q,4,_日) :-
         Q >= 32,
        _日 is Q - 31.

グレゴリオ歴(_西暦) :- true.

堺福音教会東京チャペルのサイトからの引用 :- true.