このディレクトリの索引
#  [1] 授業単元:C言語基礎 
#  [2] 問題文(含コード&リンク):  
#    
#    明治元年以降の西暦年を4桁の数で入力すると、 
#  和暦で年を表示するプログラムを作成せよ。 
#  ただし、2つの元号を持つ年 
#  は両方の年を表示すること。 
#  (例: 1989年 → 昭和64年、平成元年) 
#   
#  (2つの元号を持つ年の扱いについては 
#  余裕がある人は、月、日も入れて、その日の正しい 
#  元号を表示することによって元号を一つ表示す 
#  るプログラムとしてもよい。) 
#   提出例 
#     === プログラム === 
#     #include <stdio.h> 
#     int main() 
#     { 
#  

'明治元年以降の西暦年を4桁の数で入力すると、和暦で年を表示するプログラムを作成せよ。ただし、2つの元号を持つ年は両方の年を表示すること。' :-
        '明治元年以降の西暦年を4桁の数で入力すると'(_西暦年),
        '入力された西暦を示す4桁の数から和暦で年を表示する'(_西暦年).

'明治元年以降の西暦年を4桁の数で入力すると'(_西暦年) :-
        write('明治元年以降の西暦年を4桁の数で入力 : '),
        整数を得る(_西暦年),
        '明治元年以降の西暦年を4桁の数入力検査'(_西暦年),!.
'明治元年以降の西暦年を4桁の数で入力すると'(_西暦年) :-
        '明治元年以降の西暦年を4桁の数で入力すると'(_西暦年).

'明治元年以降の西暦年を4桁の数入力検査'(_西暦年) :-
        _西暦年 =< 9999,
        元号期間(明治,_明治元年の西暦,_,_,_,_,_),        
        _西暦年 >= _明治元年の西暦,!.
'明治元年以降の西暦年を4桁の数入力検査'(Line,_西暦年) :-
        writef('入力された %t からは明治元年以降の西暦を示す整数は得られません。再入力をお願いします。\n',[Line]),
        fail.

'入力された西暦を示す4桁の数から和暦で年を表示する'(_西暦年) :-
        findall(_和暦,(
                    西暦から和暦を得る(_西暦年,_和暦)),
                _和暦ならび),
        和暦を表示する(_西暦年,_和暦ならび).

'西暦から和暦を得る'(_西暦年,_和暦) :-
        元号期間(_元号,_開始年,_,_,_終了年,_,_),
        _西暦年 >= _開始年,
        _西暦年 =< _終了年,
        元号の開始年から和暦を得る(_西暦,_開始年,_和暦年),
        atomic_list_concat([_元号,_和暦年],_和暦).

元号の開始年から和暦年を得る(_西暦年,_開始年,_和暦年) :-
        _元号年 is _西暦年 - _開始年 + 1,
        数字年和暦年変換(_元号年,_和暦年).

数字年和暦年変換(1,元年) :- !.
数字年和暦年変換(_西暦,_和暦年) :-
        九十九までの和数字変換(_数字,_和数字),
        atomic_list_concat([_和数字,年],_和暦年),!.

九十九までの和数字変換(0,'').
九十九までの和数字変換(1,一).
九十九までの和数字変換(2,ニ).
九十九までの和数字変換(3,三).
九十九までの和数字変換(4,四).
九十九までの和数字変換(5,五).
九十九までの和数字変換(6,六).
九十九までの和数字変換(7,七).
九十九までの和数字変換(8,八).
九十九までの和数字変換(9,九).
九十九までの和数字変換(_数字,_和数字) :-
        十から十九までの和数字変換(数字,_和数字).
九十九までの和数字変換(_数字,_和数字) :-
        二十以上の和数字変換(_数字,_和数字).

十から十九までの和数字変換(_数字,_和数字) :-
        _数字 >= 10,
        _数字 =< 19,
        M is _数字 mod 10,
        九十九までの和数字変換(M,M2),
        atomic_list_concat([十,_和数字一の桁],_和数字).

二十以上の和数字変換(_数字,_和数字) :-
        _数字 >= 20,
        _数字 =< 99,
        一の桁の変換(_数字,_和数字一の桁),
        十の桁の変換(_数字,_和数字十の桁),
        atomic_list_concat([_和数字十の桁,十,_和数字一の桁],_和数字).

一の桁の変換(_数字,_和数字一の桁) :-
        _一の桁の数字 is _数字 mod 10,
        九十九までの和数字変換(_一の桁の数字,_和数字一の桁).

十の桁の変換(_数字,_和数字十の桁) :-
        _十の桁の数字 is _数字 // 10,
        九十九までの和数字変換(_十の桁の数字,_和数字十の桁).

和暦を表示する(_西暦,[_和暦]) :-
        writef('西暦%t年は和暦では%tです。\n',[_西暦,_和暦]),!.
和暦を表示する(_西暦,[_和暦_1,_和暦_2]) :-
        writef('西暦%t年は和暦では%tか%tです。\n',[_西暦,_和暦_1,_和暦_2]),!.


元号の最終日と元号の開始日が一致する日(_年,_月,_日,_先の元号,_後の元号,_改元施行注釈) :-
        元号期間(_先の元号,_年,_月,_日,_),
        元号期間(_後の元号,_年,_月,_日,_改元施行注釈),!.

元号期間(明治,1868,1,1,1912,7,30).
元号期間(大正,1912,7,30,1926,12,25).
元号期間(昭和,1926,12,25,1989,1,7).
元号期間(平成,1989,1,8,_年,_月,_日) :-
        今日(_年,_月,_日).

改元日(明治,1868,1,25,'改元は1月1日に遡って施行された') :-
        '実際の改元の勅書は1968年10月23日に出されたが1月1日に遡って施行'.
改元日(大正,1912,7,30,'改元は即日施行された') :-
        '改元は即日施行された'.
改元日(昭和,1926,12,25,'改元は即日施行された') :-
        '改元は即日施行された'.
改元日(平成,1989,1,7,'改元は翌日から施行された') :-
        '改元は翌日から施行された'.

'実際の改元の勅書は1968年10月23日に出されたが1月1日に遡って施行'.

'改元は即日施行された'.

'改元は翌日から施行された'.

今日(_年,_月,_日) :-
        shs(date,S),
        split(S,[' ',年,月,日],[_年,_月,_日|_]),!.