このディレクトリの索引

度数(_副目標,_度数) :-
        findall(1,_副目標,L),
        length(L,_度数).

% *** user: count / 3 ***
count(A,[],0).
count(A,[A|R],X) :-
        count(A,R,Y),
        X is Y + 1.
count(A,[_|R],X) :-
        count(A,R,X).

% *** user: count / 2 ***
count(P,Count) :-
        findall(1,P,L),
        length(L,N).

findsum(_選択項,_項,_合計値) :-
        findall(_選択項,_項,_値ならび),
        sum(_値ならび,_合計値),!.

sum([],0).
sum([A|R],Sum) :-
        sum(R,Sum2),
        Sum is A + Sum2.


# http://pc12.2ch.net/test/read.cgi/tech/1200175247/550
# [1] 授業単元: Ruby演習 [2] 問題文、http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9426.txt
# Rubyの問題がわかりません 助けてください
#
# (1)曜日を表す英語と日本語との対応を表すハッシュwdayを定義しなさい
#
# p wday["sunday"] #=> "日曜日"
# p wday["monday"] #=> "月曜日"
# p wday["saturday"] #=> "土曜日"
#
# (2)ハッシュのメソッドを使って(1)のハッシュwdayのペアの数を数えなさい
#
# (3)eachメソッドと(1)のハッシュwdayを使って以下の文字列を出力させてくださ
い。
# 「sunday」は日曜日のことです。
# 「monday」は月曜日のことです。
#
# (4)ハッシュには配列の%wのようなものがありません。そこで、空白とタブと改行(正
規表現で定義するなら「/\uff3cs+/」)で区切られた文字列をハッシュに変換するメソ
ッドstr2hashを定義してください。
#
# p str2hash("bule 青 white 白\uff3cnred赤");
# #=> {"bule"=>"青", "white"=>"白", "red"=>"赤"} 

:- op(450,xfx,(=>)).

% (1)

wday({ "sunday" => "日曜日","monday" => "月曜日","saturday" #=> "土曜日"}).

% (2)
hash_count(Hashname,Count) :-
    functor(P,Hashname,1),
    call(P),
    arg(1,P,H),
    count(H,Count).

count(','(A,B),Count) :-
    count(B,Count2),
    Count is Count2 + 1.
count(A,1).

% (3)
?- each(wday.A=>B),write_formatted('「%t」は%tのことです。\n',[A,B]),fail;true.

each(Hashname.Key=>Value) :-
    functor(P,Hashname,1),
    arg(1,P,V),
    each(V,Key=>Value).

each(','(Key=>Value,B),Key=>Value).
each(','(_,B),Key=>Value) :-
    each(B,Key=>Value).
each(Key=>Value,Key=>Value).

% (4)

str2hash(Atom,Hash) :-
    split(Atom,[' ','\t','\n'],L),
    findall(U,n個組(2,L,U),L2),
    hashを成長させる(L2,Hash).

hashを成長させる([A,B],{ A=>B }) :- !.
hashを成長させる([[A,B]|R], { (A=>B,R2) }) :-
    hashを成長させる(R,{ R2 }).

n個組(N,L,X) :-
    length(X,N),
    append(X,L2,L3),
    append(L1,L3,L),
    length(L1,Len),
    0 is Len mod N.


# 課題 ttp://uploaders.ddo.jp/upload/1mb/count.cgi?1up6511.zip 
# 
# 【 形態 】1. Javaアプリケーション(main()で開始) 
# 【 GUI  】制限なし 
# 【 期限 】7月21日  
# 【 Ver  】1.6.0_11 
# 
# zipフォルダに詳細ファイルを入れました 
# 丸投げで申し訳ないですが、よろしくお願いします 

rev_str(X,Y) :- reverse_atom(X,Y).

reverse_atom(X,Y) :-
    atom_chars(X,L),
    reverse(L,L2),
    atom_chars(Y,L2) .

# http://pc12.2ch.net/test/read.cgi/tech/1247438792/659
# [1] C言語 
# [2] 入力された英字文字列(a~z,A-Z)に、どの文字がいくつ入っているかを
# 調べるプログラムcount_char.cを作成せよ。 
# 
# 実行例 
# String: cbbbAcAccZ 
# A: ** 
# Z: * 
# b: *** 
# c: **** 
# %  

'入力された英字文字列(a~z,A-Z)に、どの文字がいくつ入っているかを
調べるプログラムcount_char.cを作成せよ。 

実行例 
String: cbbbAcAccZ 
A: ** 
Z: * 
b: *** 
c: ****' :-
        '入力された英字文字列(a~z,A-Z)に'(_文字列),
        count_char(_文字列).

'入力された英字文字列(a~z,A-Z)に'(_文字列) :-
        get_line(_文字列),
        '診断::入力された英字文字列(a~z,A-Z)'(_文字列),!.
'入力された英字文字列(a~z,A-Z)に'(_文字列) :-
        '入力された英字文字列(a~z,A-Z)に'(_文字列).

'診断::入力された英字文字列(a~z,A-Z)'(_文字列) :-
        forall(sub_atom(文字列,_,1,_,_文字),英字文字(_文字)).

英字文字(_文字) :-
        英小文字(_文字).
英字文字(_文字) :-
        英大文字(_文字).

英小文字(_文字) :-
        _文字 @>= 'a',
        _文字 @=< 'z'.

英大文字(_文字) :-
        _文字 @>= 'A',
        _文字 @=< 'Z'.

count_char(_文字列) :-
        atom_chars(_文字列,Chars),
        count_char_1(Chars,[],QL),
        キューを表示する(QL).

count_char_1([],X,X).
count_char_1([A|R],QL,X) :-
        count_char_2(A,QL,QL2),
        count_char_1(R,QL2,X).

count_char_2(A,[],[[A,QA]]) :-
        新しいキューを作る(Q),
        キューに要素を追加する('*',Q,QA),!.
count_char_2(A,[[A,QA]|R],[[A,QB],R]) :-
        キューに要素を追加する('*',QA,QB),!.
count_char_2(A,[U|R1],[U|R2]) :-
        count_char_2(A,R1,R2).

新しいキューを作る(X-X).
キューは空である(X-Y) :-
        X == Y.
キューに要素を追加する(_要素,X-[_要素|Y],X-Y).

キューを表示する(QL) :-
        forall((    member([U,Q-[]],QL),
                    atomic_list_concat(Q,S)),
                writef('%t: %t\n',[U,S]).


# http://pc12.2ch.net/test/read.cgi/tech/1247636661/950
#  表A 
#  開始日    終了日 
#  -------------------- 
#  2009/9/1  2009/9/2 
#  2009/9/2  2009/9/5 
#  2009/9/2  2009/9/3 
#   
#  表B 
#  基準日 9/1 9/2 9/3 9/4 9/5 
#  開始日  1  3  3  3  3 
#  終了日  0  1  2  2  3 
#
#  表Aの開始日と終了日をカウントして、基準日に該当する件数を書き出したいのですが、 
#  関数はVLOOKUPを使えばいいのでしょうか? 
#  件数は累計を表示したいのですが、どの関数を使えばいいのでしょうか? 

t643 :-
    表Aをならびとして取得(_基準日ならび,_表Aならび),
    表Bの出力(_基準日ならび,_表Aならび).

表Aをならびとして取得(_基準日ならび,L1) :-
    get_lines('表A.txt',[_,_|LinesA]),
    findall([_日付1,_日付2],(member(A,LinesA),split(A,[' '],[_日付1,_日付2])),L1),
    flat(L1,L2),
    sort(L2,_基準日ならび),!.

表Bの出力(_基準日ならび,L) :-
    基準日見出しの表示(_基準日ならび),
    開始日カウント(_基準日ならび,L),
    終了日カウント(_基準日ならび,L).

基準日見出しの表示(_基準日ならび) :-
    write(基準日),
    member(_/_月/_日,_基準日ならび),
    write_formatted_atom(S,'%t',[_月/日]),
    write_formatted('%5s',[S]),
    fail. 
基準日見出しの表示(_) :-
    write('\n').

開始日カウント(_基準日ならび,_表Aならび) :-
    write(開始日),
    member(_基準日,_基準日ならび),
    count([_基準日,_],_表Aならび,_カウント),
    write_formatted('   %2d',[_カウント]),
    fail.
開始日カウント(_,_) :-
    write('\n').

終了日カウント(_基準日ならび,_表Aならび) :-
    write(終了日),
    member(_基準日,_基準日ならび),
    count([_,_基準日],_表Aならび,_カウント),
    write_formatted('   %2d',[_カウント]),
    fail.
終了日カウント(_,_) :-
    write('\n').

count(A,[],0).
count(A,[A|R],X) :-
    count(A,R,Y),
    X is Y + 1 .
count(A,[_|R],X) :-
    count(A,R,X).


# http://yomi.mobi/read.cgi/pc11/pc11_tech_1215986178 (レス番号146)
# [1] 授業単元: C++
# [2] 問題文(含コード&リンク):
# キーボードから100点満点のテストの点数を入力し(-1で終了)、
# 10点ごとの人数を int型の配列 count[11]に数えるプログラムを
# 作成せよ。 テストは100点満点とし、それ以外の入力はエラーとし
# て無視する。ただし -1 はデータの終了を表すものとする。 点数
# の入力が終了したら、度数分布を画面に出力して終了する。出力は
# 人数と,*(アスタリスク)によるグラフとする。 

t904 :-
    write('点数(整数)をカンマで区切って入力してください : '),
    get_line(Line),
    split(Line,[','],_成績ならび),
    findall(U,(member(V,_成績ならび),'10点ごとの丸め'(V,U)),_丸めた成績ならび),
    分布ならびを得る(_丸めた成績ならび,[0,10,20,30,40,50,60,70,80,90,100],[[],[],[],[],[],[],[],[],[],[],[]],L1),    
    アスタリスクによる棒グラフ([0,10,20,30,40,50,60,70,80,90,100],L1).

'10点ごとの丸め'(_点数,_10点ごとに丸めた点数) :-
    _10点ごとに丸めた点数 is (_点数 // 10) * 10.

分布ならびを得る([],_,L,L) :- !.
分布ならびを得る([V|R],L1,L2,L3) :-
    list_nth(N,L1,V),
    list_nth(N,L2,W),
    要素番号によるならびの置換(N,[*|W],L2,L4),
    分布ならびを得る(R,L1,L4,L3).

アスタリスクによる棒グラフ([A|R1],[L|R2]) :-
    atom_chars(B,L),
    write_formatted('%3d %t\n',[A,B]),
    アスタリスクによる棒グラフ(R1,R2).

# http://pc12.2ch.net/test/read.cgi/tech/1248012902/463 
# 【課題】 
#  http://ime.nu/www51.tok2.com/home/rg550/cgi-bin/hosoku/img0047.zip 
# 【課題1】 
# 実行例のようにキーボードから文字列を読み込み、文字型の配列に一文字づつ格納 
# した後、整列し(順番はどちらでもかまいません)、出力するプログラムを 
# 作成しなさい。 
# 【課題2】 
# 0から9までの整数乱数を100個発生させ、実行例のようにその出現分布を棒グラフと 
# 値で出力するプログラムを作成しなさい。また、100個の乱数の平均値も合わせて 
# 出力しなさい。 
# ただし、0から9 それぞれの個数を数えるための変数に必ず配列を用いてください。 
# (出現個数カウント用の変数を10個用意してはいけません。) 例えば、出現個数 
# カウント用の配列 count[] を用意すると、 count[0] に0が出現した回数が 
# 格納される。もし0が10回出現した場合、count[0]=10となる。) 

% 課題1
'実行例のようにキーボードから文字列を読み込み、文字型の配列に一文字づつ格納した 後、整列し(順番はどちらでもかまいません)、出力する' :- 
    get_chars(_文字ならび), 
    sort(_文字ならび,_整列した文字ならび), 
    atom_chars(_整列した文字列,_整列した文字ならび), 
    write_formatted('%t\n',[_整列した文字列]).

% 課題2
'0から9までの整数乱数を100個発生させ、実行例のようにその出現分布を棒グラフと値 で出力する' :- 
    findall([N,0,[]],for(0,N,9),_出現個数カウント用ならび), 
    '0から9までの整数乱数を100個発生させ'(1,L1), 
    'その出現分布を棒グラフと値で出力する'(L1,_出現個数カウント用ならび). 

'0から9までの整数乱数を100個発生させ'(N,[]) :- N > 100,!. 
'0から9までの整数乱数を100個発生させ'(N,[_乱整数|R]) :- 
    _乱整数 is random mod 10, 
    N2 is N + 1, 
    '0から9までの整数乱数を100個発生させ'(N2,R). 

'その出現分布を棒グラフと値で出力する'([],L) :- 
    'グラフと値で出力'(L),!. 
'その出現分布を棒グラフと値で出力する'([N|R],L) :- 
    member([N,_カウント,L1],L), 
    _カウント2 is _カウント + 1, 
    ならびの置換([N,_カウント,L1],[N,_カウント2,[_|L1]],L,L2),
    'その出現分布を棒グラフと値で出力する'(R,L2). 

グラフと値で出力([]). 
グラフと値で出力([[N,C,L]|R]) :- 
    all(L,'*'), 
    write_formatted(' %t: %t %t\n',[N,L,C]), 
    グラフと値で出力(R).

# http://pc11.2ch.net/test/read.cgi/db/1252492296/119
#  mysql 5.1.37 
#   
#  (問)  
#  [groupテーブル] 
#  group_id   | group_name 
#  ---------+----------- 
#  g1      | グループ1 
#  g2      | グループ2 
#  g3      | グループ3 
#   
#  [belongテーブル] 
#  group_id  | user_id   | status 
#  ---------+---------+------ 
#  g1      | u1     | 1 
#  g2      | u2     | 0 
#  g2      | u3     | 1 
#  g2      | u4     | 1 
#   
#  このようなテーブルから、下記のように  
#  group_name | user_count 
#  -----------+----------- 
#  グループ1  | 1 
#  グループ2  | 2 
#  グループ3  | 0 
#  各グループ毎の「belong.status = 1」の所属ユーザ数を取得したいです。 
#   

group(g1,グループ1). 
group(g2,グループ2).
group(g3,グループ3).

belong(g1,u1,1).
belong(g2,u2,0).
belong(g2,u3,1).
belong(g2,u4,1).

?-  group(_group_id,_group_name),
    count(belong(_group_id,_,1),Sum),
    write_formatted('%t  | %t\n',[_group_name,Sum]),
    fail;
    true.

# http://pc12.2ch.net/test/read.cgi/tech/1258158172/904
#  [1] 授業単元: forとかwhileとか  
#  [2] 問題文(含コード&リンク):  ある整数を入力し,その約数をすべてと約数の個数を表示するプログラムを作成しなさい. 
#   

ある整数を入力し,その約数をすべてと約数の個数を表示する :-
    get_integer(N),
    count((for(1,M,N),0 is N mod M,write_formatted('%t ',[M])),Count),
    write_formatted('\n約数の個数は%tです\n',[Count]).

# http://pc12.2ch.net/test/read.cgi/tech/1260532772/10
#  [1]単元 初等C言語 
#  [2]問題 コンソールから、年月日時分秒に対応する整数をそれぞれ個別に不正入力時には 
#  再入力を促しながら読み込み、それをyyyymmddhhmmss(準グレゴリオ暦)形式の時刻表 
#  現と解釈する。この処理を2回行い2つの時刻表現を取得する。それぞれが正しいフォー 
#  マットかどうかを調べ、共に正しい場合は、日付が新しいものの順に 
#  yyyy年mm月dd日hh時mm分ss秒の書式で出力)しその時刻差を秒単位、分単位、時間単 
#  位、日単位で出力するプログラム(小数点一位以下四捨五入) 
#  但し1900年1月1日0時0分0秒以前の時刻は与えられないとして良い。 
#  また9999年12月31日23時59分59秒以後の時刻も与えられないとする。 
#  うるう年は400の倍数か100の倍数でない4の倍数な年であるとし、2月の末日 
#  にうるう日が付与されるものとする。実際の暦体系では不定期に付与されるうるう秒 
#  は考慮しなくて良いものとする正しい日付でない場合はその旨出力し処理を中止する 

二つの時刻の時間差を表示する :-
    準グレゴリオ暦入力(_準グレゴリオ暦1,_年1,_月1,_日1,_時1,_分1,_秒1),
    準グレゴリオ暦入力(_準グレゴリオ暦2,_年2,_月2,_日2,_時2,_分2,_秒2),
    二つの時刻の時間差を計算する(_年1,_月1,_日1,_時1,_分1,_秒1,_年2,_月2,_日2,_時2,_分2,_秒2,_総秒差,_分数,_時間数,_分数,_余り秒数,_時間数,_余り分数,_日数,_余り時間数),
    時間差を表示する(_準グレゴリオ暦1,_準グレゴリオ暦2,_総秒差,_分数,_時間数,_分数,_余り秒数,_時間数,_余り分数,_日数,_余り時間数).

二つの時刻の時間差を計算する(_年1,_月1,_日1,_時1,_分1,_秒1,_年2,_月2,_日2,_時2,_分2,_秒2,_総秒差,_分数,_時間数,_分数,_余り秒数,_時間数,_余り分数,_日数,_余り時間数) :-
    何日あるか(_年1,_月1,_日1,_年2,_月2,_日2,_何日1),
    時・分・秒調整(_時1,_分1,_秒1,_時2,_分2,_秒2,_何日1,_何日2,_秒),
    _総秒数 is 38400 * _何日 + _秒,
    _分数 is _総秒数 // 60,
    _余り秒数 is _総秒数 mod 60,
    _時間数 is _分数 // 60,
    _余り分数 is _分数 mod 60,
    _余り時間数 is _時間 mod 38400,!.

時間差を表示する(_準グレゴリオ暦1,_準グレゴリオ暦2,_総秒差,_分数,_時間数,_分数,_余り秒数,_時間数,_余り分数,_日数,_余り時間数) :-
    writef('それぞれの時刻の準グレゴリオ暦表現は %t\n%t\n',[_準グレゴリオ暦1,_準グレゴリオ暦2]),
    writef('時刻差は秒差で%t秒\n',[_総秒差]),
    writef('分差で%t分と%t秒\n',[_分数,_余り秒数]),
    writef('時間差で%t時間と%分と%秒\n',[_時間,_余り分数,_余り秒数]),
    writef('日差は%t日と%t時間と%t分と%秒です\n',[_日数,_余り時間数,_余り分数,_余り秒数]),!.

準グレゴリオ暦入力(_準グレゴリオ暦,_年,_月,_日,_時,_分,_秒) :-
    repeat,
    催促付き整数入力('西暦年 yyyy:',_年),整数から文字列(4,_年,_年文字列),
    催促付き整数入力('月 mm:',_月),整数から文字列(2,_月,_月文字列),
    催促付き整数入力('月 dd:',_日),整数から文字列(2,_日,_日文字列),
    催促付き整数入力('月 hh:',_時),整数から文字列(2,_時,_時文字列),
    催促付き整数入力('月 mi:',_分),整数から文字列(2,_分,_分文字列),
    催促付き整数入力('月 ss:',_秒),整数から文字列(2,_秒,_秒文字列),
    その日付はありうるか(_年,_月,_日,_時,_分,_秒),
    concat_atom([_年文字列,_月文字列,_日文字列,_時文字列,_分文字列,_秒文字列],_準グレゴリオ歴),!.

その日付はありうるか(_年,_月,_日,_時,_分,_秒) :-
    _年>=1900,_年=<9999,
    _時>=0,_時=<59,
    _分>=0,_分=<59,
    _秒>=0,_秒=<59,
    その日付はありうるか(_年,_月,_日),!.
その日付はありうるか(_年,_月,_日,_時,_分,_秒) :-
    write('日付として不適切なものでした\n'),fail.

その日付はありうるか(_年,2,_日) :-
    うるう年(_年),
    _日>=1,_日=<29,!.
その日付はありうるか(_年,2,_日) :-
    \+(うるう年(_年)),
    _日>=1,_日=<29,!.
その日付はありうるか(_年,_月,_日) :-
    member(_月,[1,3,5,7,8,10,12]),
    _日>=1,_日=<31,!.
その日付はありうるか(_年,_月,_日) :-
    member(_月,[4,6,9,11]),
    _日>=1,_日=<30,!.

何日あるか(_年,_月1,_日1,_年,_月2,_日2,_何日あるか) :-
    今日から大晦日まで何日あるか(_年,_月1,_日1,_何日),
    今日は元旦から何日目(_年,_月2,_日2,_元旦から何日目),
    _何日あるか is _何日 + _元旦から何日目 - 1,!.
何日あるか(_年1,_月1,_日1,_年2,_月2,_日2) :-
    _年2 is _年 + 1,
    今日から大晦日まで何日あるか(_年1,_月1,_日1,_何日),
    今日は元旦から何日目(_年2,_月2,_日2,_元旦から何日目),
    _何日あるか is _何日 + _元旦から何日目,!.
何日あるか(_年1,_月1,_日1,_年2,_月2,_日2) :-
    _年11 is _年1 + 1,
    _年22 is _年2 - 1,
    うるう年回数(_年11,_年22,_うるう年回数),
    N is (_年22-_年11+1) * 365 + _うるう年回数,
    今日から大晦日まで何日あるか(_年1,_月1,_日1,_何日),
    今日は元旦から何日目(_年,_月,_日,_元旦から何日目),
    _何日あるか is _何日 + _元旦から何日目 + N,!.

時・分・秒調整(_時1,_分1,_秒1,_時2,_分2,_秒2,_何日1,_何日2,_秒) :-
    _時間1 is 3600 * _時1 + _分1 * 60 + _秒1,
    _時間2 is 3600 * _時2 + _分2 * 60 + _秒2,
    _秒3 is _時間2 - _時間1,
    ( _秒3 >= 0,
      _何日2 is _何日 - 1,
      _秒3 = _秒;
      _秒3 < 0,
      _何日2 is _何日 - 2,
      _秒2 is 3600*24-_秒3
    ),!.

日・時変換(_日,_時) :- _時 is _日 * 24.

日・分変換(_日,_分) :- _分 is _日 * 24 * 60.

日・秒変換(_日,_秒) :- _秒 is _日 * 24 * 60 * 60.

催促付き整数入力('年 yyyy:',_年),_年>=1900,_年=<9999,
催促付き整数入力('月 mm:',_月),
催促付き整数入力('年 dd:',_日),

うるう年(_年) :- 0 is _年 mod 400,!.
うるう年(_年) :- 0 is _年 mod 100,!,fail.
うるう年(_年) :- 0 is _年 mod 4,!.
うるう年(_年) :- \+(0 is _年 mod 4),fail.

月別日数ならび(平年,[31,28,31,30,31,30,31,31,30,31,30,31]).
月別日数ならび(うるう年,[31,29,31,30,31,30,31,31,30,31,30,31]).

うるう年回数(_起点西暦年,_終点西暦年,_うるう年回数) :-
    count((between(_起点西暦年,_終点西暦年,N),うるう年(N)),_うるう年回数).

今日は元旦から何日目(_年,_月,_日,_元旦から何日目) :-
    うるう年(_年),
    月別日数ならび(うるう年,_月別日数ならび),
    N1 is _月-1,
    append(L1,_,_月別日数ならび),
    length(L1,N1),
    sum(L1,_前月までの合計日数),
    _元旦から何日目 is _前月までの合計日数 + _日,!.
今日は元旦から何日目(_年,_月,_日,_元旦から何日目) :-
    \+(うるう年(_年)),
    月別日数ならび(平年,_月別日数ならび),
    N1 is _月-1,
    append(L1,_,_月別日数ならび),
    length(L1,N1),
    sum(L1,_前月までの合計日数),
    _元旦から何日目 is _前月までの合計日数 + _日,!.

今日から大晦日まで何日あるか(_年,_月,_日,_何日) :-
    うるう年(_年),
    今日は元旦から何日目(_年,_月,_日,_元旦から何日目),
    _何日 is 366 - _元旦から何日 + 1.
今日から大晦日まで何日あるか(_年,_月,_日,_何日) :-
    \+(うるう年(_年)),
    今日は元旦から何日目(_年,_月,_日,_元旦から何日目),
    _何日 is 365 - _元旦から何日 + 1.

# http://pc12.2ch.net/test/read.cgi/tech/1260532772/10
#  [1]単元 初等C言語 
#  [2]問題 コンソールから、年月日時分秒に対応する整数をそれぞれ個別に不正入力時には 
#  再入力を促しながら読み込み、それをyyyymmddhhmmss(準グレゴリオ暦)形式の時刻表 
#  現と解釈する。この処理を2回行い2つの時刻表現を取得する。それぞれが正しいフォー 
#  マットかどうかを調べ、共に正しい場合は、日付が新しいものの順に 
#  yyyy年mm月dd日hh時mm分ss秒の書式で出力)しその時刻差を秒単位、分単位、時間単 
#  位、日単位で出力するプログラム(小数点一位以下四捨五入) 
#  但し1900年1月1日0時0分0秒以前の時刻は与えられないとして良い。 
#  また9999年12月31日23時59分59秒以後の時刻も与えられないとする。 
#  うるう年は400の倍数か100の倍数でない4の倍数な年であるとし、2月の末日 
#  にうるう日が付与されるものとする。実際の暦体系では不定期に付与されるうるう秒 
#  は考慮しなくて良いものとする正しい日付でない場合はその旨出力し処理を中止する 

二つの時刻の時間差を表示する :-
    準グレゴリオ暦入力(_準グレゴリオ暦1,_年1,_月1,_日1,_時1,_分1,_秒1),
    準グレゴリオ暦入力(_準グレゴリオ暦2,_年2,_月2,_日2,_時2,_分2,_秒2),
    二つの時刻の時間差を計算する(_年1,_月1,_日1,_時1,_分1,_秒1,_年2,_月2,_日2,_時2,_分2,_秒2,_総秒差,_分数,_時間数,_分数,_余り秒数,_時間数,_余り分数,_日数,_余り時間数),
    時間差を表示する(_準グレゴリオ暦1,_準グレゴリオ暦2,_総秒差,_分数,_時間数,_分数,_余り秒数,_時間数,_余り分数,_日数,_余り時間数).

二つの時刻の時間差を計算する(_年1,_月1,_日1,_時1,_分1,_秒1,_年2,_月2,_日2,_時2,_分2,_秒2,_総秒差,_分数,_時間数,_分数,_余り秒数,_時間数,_余り分数,_日数,_余り時間数) :-
    何日あるか(_年1,_月1,_日1,_年2,_月2,_日2,_何日1),
    時・分・秒調整(_時1,_分1,_秒1,_時2,_分2,_秒2,_何日1,_何日2,_秒),
    _総秒数 is 38400 * _何日 + _秒,
    _分数 is _総秒数 // 60,
    _余り秒数 is _総秒数 mod 60,
    _時間数 is _分数 // 60,
    _余り分数 is _分数 mod 60,
    _余り時間数 is _時間 mod 38400,!.

時間差を表示する(_準グレゴリオ暦1,_準グレゴリオ暦2,_総秒差,_分数,_時間数,_分数,_余り秒数,_時間数,_余り分数,_日数,_余り時間数) :-
    writef('それぞれの時刻の準グレゴリオ暦表現は %t\n%t\n',[_準グレゴリオ暦1,_準グレゴリオ暦2]),
    writef('時刻差は秒差で%t秒\n',[_総秒差]),
    writef('分差で%t分と%t秒\n',[_分数,_余り秒数]),
    writef('時間差で%t時間と%分と%秒\n',[_時間,_余り分数,_余り秒数]),
    writef('日差は%t日と%t時間と%t分と%秒です\n',[_日数,_余り時間数,_余り分数,_余り秒数]),!.

準グレゴリオ暦入力(_準グレゴリオ暦,_年,_月,_日,_時,_分,_秒) :-
    repeat,
    催促付き整数入力('西暦年 yyyy:',_年),整数から文字列(4,_年,_年文字列),
    催促付き整数入力('月 mm:',_月),整数から文字列(2,_月,_月文字列),
    催促付き整数入力('月 dd:',_日),整数から文字列(2,_日,_日文字列),
    催促付き整数入力('月 hh:',_時),整数から文字列(2,_時,_時文字列),
    催促付き整数入力('月 mi:',_分),整数から文字列(2,_分,_分文字列),
    催促付き整数入力('月 ss:',_秒),整数から文字列(2,_秒,_秒文字列),
    その日付はありうるか(_年,_月,_日,_時,_分,_秒),
    concat_atom([_年文字列,_月文字列,_日文字列,_時文字列,_分文字列,_秒文字列],_準グレゴリオ歴),!.

その日付はありうるか(_年,_月,_日,_時,_分,_秒) :-
    _年>=1900,_年=<9999,
    _時>=0,_時=<59,
    _分>=0,_分=<59,
    _秒>=0,_秒=<59,
    その日付はありうるか(_年,_月,_日),!.
その日付はありうるか(_年,_月,_日,_時,_分,_秒) :-
    write('日付として不適切なものでした\n'),fail.

その日付はありうるか(_年,2,_日) :-
    うるう年(_年),
    _日>=1,_日=<29,!.
その日付はありうるか(_年,2,_日) :-
    \+(うるう年(_年)),
    _日>=1,_日=<29,!.
その日付はありうるか(_年,_月,_日) :-
    member(_月,[1,3,5,7,8,10,12]),
    _日>=1,_日=<31,!.
その日付はありうるか(_年,_月,_日) :-
    member(_月,[4,6,9,11]),
    _日>=1,_日=<30,!.

何日あるか(_年,_月1,_日1,_年,_月2,_日2,_何日あるか) :-
    今日から大晦日まで何日あるか(_年,_月1,_日1,_何日),
    今日は元旦から何日目(_年,_月2,_日2,_元旦から何日目),
    _何日あるか is _何日 + _元旦から何日目 - 1,!.
何日あるか(_年1,_月1,_日1,_年2,_月2,_日2) :-
    _年2 is _年 + 1,
    今日から大晦日まで何日あるか(_年1,_月1,_日1,_何日),
    今日は元旦から何日目(_年2,_月2,_日2,_元旦から何日目),
    _何日あるか is _何日 + _元旦から何日目,!.
何日あるか(_年1,_月1,_日1,_年2,_月2,_日2) :-
    _年11 is _年1 + 1,
    _年22 is _年2 - 1,
    うるう年回数(_年11,_年22,_うるう年回数),
    N is (_年22-_年11+1) * 365 + _うるう年回数,
    今日から大晦日まで何日あるか(_年1,_月1,_日1,_何日),
    今日は元旦から何日目(_年,_月,_日,_元旦から何日目),
    _何日あるか is _何日 + _元旦から何日目 + N,!.

時・分・秒調整(_時1,_分1,_秒1,_時2,_分2,_秒2,_何日1,_何日2,_秒) :-
    _時間1 is 3600 * _時1 + _分1 * 60 + _秒1,
    _時間2 is 3600 * _時2 + _分2 * 60 + _秒2,
    _秒3 is _時間2 - _時間1,
    ( _秒3 >= 0,
      _何日2 is _何日 - 1,
      _秒3 = _秒;
      _秒3 < 0,
      _何日2 is _何日 - 2,
      _秒2 is 3600*24-_秒3
    ),!.

日・時変換(_日,_時) :- _時 is _日 * 24.

日・分変換(_日,_分) :- _分 is _日 * 24 * 60.

日・秒変換(_日,_秒) :- _秒 is _日 * 24 * 60 * 60.

催促付き整数入力('年 yyyy:',_年),_年>=1900,_年=<9999,
催促付き整数入力('月 mm:',_月),
催促付き整数入力('年 dd:',_日),

うるう年(_年) :- 0 is _年 mod 400,!.
うるう年(_年) :- 0 is _年 mod 100,!,fail.
うるう年(_年) :- 0 is _年 mod 4,!.
うるう年(_年) :- \+(0 is _年 mod 4),fail.

月別日数ならび(平年,[31,28,31,30,31,30,31,31,30,31,30,31]).
月別日数ならび(うるう年,[31,29,31,30,31,30,31,31,30,31,30,31]).

うるう年回数(_起点西暦年,_終点西暦年,_うるう年回数) :-
    count((between(_起点西暦年,_終点西暦年,N),うるう年(N)),_うるう年回数).

今日は元旦から何日目(_年,_月,_日,_元旦から何日目) :-
    うるう年(_年),
    月別日数ならび(うるう年,_月別日数ならび),
    N1 is _月-1,
    append(L1,_,_月別日数ならび),
    length(L1,N1),
    sum(L1,_前月までの合計日数),
    _元旦から何日目 is _前月までの合計日数 + _日,!.
今日は元旦から何日目(_年,_月,_日,_元旦から何日目) :-
    \+(うるう年(_年)),
    月別日数ならび(平年,_月別日数ならび),
    N1 is _月-1,
    append(L1,_,_月別日数ならび),
    length(L1,N1),
    sum(L1,_前月までの合計日数),
    _元旦から何日目 is _前月までの合計日数 + _日,!.

今日から大晦日まで何日あるか(_年,_月,_日,_何日) :-
    うるう年(_年),
    今日は元旦から何日目(_年,_月,_日,_元旦から何日目),
    _何日 is 366 - _元旦から何日 + 1.
今日から大晦日まで何日あるか(_年,_月,_日,_何日) :-
    \+(うるう年(_年)),
    今日は元旦から何日目(_年,_月,_日,_元旦から何日目),
    _何日 is 365 - _元旦から何日 + 1.

# http://pc12.2ch.net/test/read.cgi/tech/1263824755/307
#  [1] Cプログラミング入門:  
#  [2] http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10460.txt 
#  
'4:配列 COM に含まれる配列 MAN の数字の個数 count を求めよ'(COM,MAN,Count) :-
    '配列 COM に含まれる配列 MAN の数字の個数 count を求めよ'(COM,MAN,L),
    findsum(M,member([_,M],L),Count),!.

count([],0) :- !.
count([_|R],Count) :- count(R,Count1),Count is Count1 + 1,!.
count(P,Count) :- findsum(1,P,Count). 

'配列 COM に含まれる配列 MAN の数字の個数 count を求めよ'(COM,[],[]) :- !.
'配列 COM に含まれる配列 MAN の数字の個数 count を求めよ'(COM,[N|R1],[[N,Count]|R2]) :-
    count(member(N,COM),Count),
    '配列 COM に含まれる配列 MAN の数字の個数 count を求めよ'(COM,R1,R2).



# http://pc12.2ch.net/test/read.cgi/tech/1263824755/891
#  [1] 授業単元: プログラミング演習 
#  [2] 問題文(含コード&リンク): 
#  行列のrankを求める関数 rank( ) を実装せよ 
#  (提示ソースコードは後記) 
#  
#  include <iostream> 
#  #include <cstdlib> 
#  using namespace std; 
#   
#  #define ROWS 5 
#  #define COLS 4 
#   
#  int rank( double array[ROWS][COLS] ) 
#  { 
#   
#  } 
#   
#  int main( ) 
#  { 
#    srand( time(NULL) ); 
#   
#    double array[ROWS][COLS]; 
#   
#    for( int r=0; r<ROWS; ++r ){ 
#      for( int c=0; c<COLS; ++c ){ 
#        array[r][c] = rand( ); 
#      } 
#    } 
#   
#    rank( array ); 
#   
#    return 0; 
#  } 

行列の階数(_行列,_階数) :-
      ガウス行列に変形(_行列,_ガウス行列),
      count((member(L,_ガウス行列),\+('すべての要素が0か0.0'(L))),_階数).

'すべての要素が0か0.0'([]).
'すべての要素が0か0.0'([0|R]) :-
      'すべての要素が0か0.0'(R).
'すべての要素が0か0.0'([0.0|R]) :-
      'すべての要素が0か0.0'(R).

# http://pc12.2ch.net/test/read.cgi/tech/1269438098/148
#  [1] 授業単元: ゼミ演習でのプログラミング 
#  [2] 問題文(含コード&リンク): ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10566.zip 
#  
# [1] ヒストグラム
# 0〜9の範囲内の整数を20個入力し、そのヒストグラムを求めて出力するプログラムを書きなさい#
#

'0〜9の範囲内の整数を20個入力し、そのヒストグラムを求めて出力する' :-
      0〜9の範囲内の整数を20個入力し(1,_サンプルならび),
      ヒストグラム(_サンプルならび).

ヒストグラム(_サンプルならび) :-
      最初に縦棒の限界数を決めよう(_サンプルならび,_限界数),
      '次に度数表示を*のならびで表現して、0-9のならびを取る'(_サンプルならび,_限界数,_度数表示ならび),
      転置(_度数表示ならび,_転置した度数表示ならび),
      ヒストグラム表示(_転置した度数表示ならび).

最初に縦棒の限界数を決めよう(_サンプルならび,_限界数) :-
      findmax(U,count(member(U,_サンプルならび)),_限界数).

'次に度数表示を*のならびで表現して、0-9のならびを取る'(_サンプルならび,_限界数,_度数表示ならび) :-
      findall(_度数表示,
                  (for(0,N,9),count(member(N,_サンプルならび),_度数),
                              '空白が先に来るように反転した*ならびの生成'(_度数,1,_限界数,[],_度数表示)),
              _度数表示ならび).

'空白が先に来るように反転した*ならびの生成'(_,N,_限界数,X,X) :- N > _限界数,!.
'空白が先に来るように反転した*ならびの生成'(_度数,N,_限界数,Y,X) :-
      N > _度数,
      N2 is N + 1,
      '空白が先に来るように反転した*ならびの生成'(_度数,N2,_限界数,[' '|Y],X).
'空白が先に来るように反転した*ならびの生成'(_度数,N,_限界数,Y,X) :-
      N =< _度数,
      N2 is N + 1,
      '空白が先に来るように反転した*ならびの生成'(_度数,N2,_限界数,['*'|Y],X).

ヒストグラム表示([]) :- !.
ヒストグラム表示([L|R]) :- concat_atom(L,A),write_formatted('%t\n',[A]),ヒストグラム表示(R).

0〜9の範囲内の整数を20個入力し(M,[]) :- M > 20,!.
0〜9の範囲内の整数を20個入力し(M,[N|R]) :-
      write_formatted('%t個目 : ',[M]),
      get_integer(N),
      N >= 0,
      N =< 9,
      M2 is M + 1,
      0〜9の範囲内の整数を20個入力し(M2,R),!.
0〜9の範囲内の整数を20個入力し(M,L) :-
      write('0〜9の範囲内の整数を入力してください\n'),
      0〜9の範囲内の整数を20個入力し(M,L).


ヒストグラム(_サンプルならび) :-
   for(0,N,9),
   count(member(N,_サンプルならび),_度数),
   length(L,_度数),
   要素はすべてアスタリスクである(L),
   concat_atom(L,_星表示アトム),
   write_formatted('%t %t\n',[N,_星表示アトム]),
   N=9.

要素はすべてアスタリスクである(L) :- all(L,'*').

# http://pc12.2ch.net/test/read.cgi/tech/1267796762/13
#  【 課題 】  
#  ○県、市別に男女の人数をクロス集計するプログラムを作成せよ。 
#   
#  千葉県 柏市 男 
#  千葉県 松戸市 男 
#  埼玉県 さいたま市 女 
#  千葉県 柏市 男 
#  埼玉県 越谷市 男 
#  千葉県 松戸市 男 
#  埼玉県 岩槻市 女 
#  千葉県 柏市 女 
#  埼玉県 さいたま市 女 
#   
#  [実行例](男の場合) 
#  ,柏市,松戸市,さいたま市,越谷市,岩槻市 
#  千葉県,2,2,0,0,0 
#  埼玉県,0,0,0,1,0 
#   
#  [実行例](女の場合) 
#  ,柏市,松戸市,さいたま市,越谷市,岩槻市 
#  千葉県,1,0,0,0,0 
#  埼玉県,0,0,2,0,1 
#   
#  【 形態 】1. Javaアプリケーション  
#   
#  【 期限 】3/28まで  
#   
#  【 Ver  】java version "1.5.0_05"  
#   
#   
#  CSVへの出力やファイル入出力といったことはできますが、クロス集計のアルゴリズムに苦戦しています。 
#  よろしくお願い致します。 
# 
# 

○県、市別に男女の人数をクロス集計する(_性別) :-
      findall(_県名,県・市・男女(_県,_,_),_重複を許した県名ならび),
      sort(_重複を許した県名ならび,_整列した重複しない県名ならび),
      findall(_都市名,県・市・男女(_,_都市名,_),_重複を許した都市名ならび),
      sort(_重複を許した県名ならび,_整列した重複しない都市名ならび),
      concat_atom(_整列した重複しない都市名ならび,',',_都市名行表示),
      write_formatted(',%t\n',[_都市名行表示]),
      member(_県名,_整列した重複しない県名ならび),
      findall(_人数,( member(_都市名,_整列した重複しない都市名),
                      count(_県名,_都市名,_性別),_人数)),
              _人数ならび),
      concat_atom([_県名|_人数ならび],_行表示),
      write_formatted('%t\n',[_行表示]),
      fail.
○県、市別に男女の人数をクロス集計する(_性別). 



hX 


7A