このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1342966104/793
#  [1] 授業単元:プログラミング  
#  [2] 問題文:  
#  http://ime.nu/codepad.org/3HrmfsVo 
#  http://ime.nu/codepad.org/InxgbSAZ 
#  http://ime.nu/codepad.org/99RFoVNY 
#  
#  /*
#  プログラムの引数に書籍データのファイルと列数(a) を与える。書籍データのファイルは
#  c2md.csv である。
#  
#  各行が1つの書籍データを表している。書籍データは出版社名、書名、発行年、本体価格4つの属性を持ち、
#  それらをカンマ(,)で区切って表している。ただし書名にカンマ(,)が含まれる場合には、書名は二重引用符
#  (”)で囲まれている。発行年、本体価格は正の整数値で記述されており、情報がない不明の場合は記述がない。
#  
#  a で指定された列だけを表示せよ。
#  ただし1行を出版社出版社名を表す文字の配列、書名を表す文字の配列、発行年を表す整数、本体価格
#  を表す整数に分解する関数bunkatu を実装することで実現せよ。
#  
#  */
#  /*
#  プログラムの引数に書籍データのファイル(c2md.csv) を与える。各出版社が2000 年から2012 年ま
#  でに出版した本の冊数を求め、その冊数の多い順に表示せよ。
#  ただし出版社名(name)とその出版社が2000 年から2012 年までに出版した本の冊数(pub)を表す以
#  下の構造体bkcmpy を用意する。
#  struct bkcmpy {
#  char name[100];
#  int pub;
#  };
#  各出版社に対して、このbkcmpy を作成し、この構造体の情報を出力することでプログラムを作成せよ。
#  
#  プログラムでは、出版社が全部で150 社以下であることは仮定し、bkcmpy のポインターの配列
#  bkcmpydb[150] を用意する。関数touroku ではbkcmpydb と読み込んだ出版社名cname を与える。
#  cname が既にbkcmpydb に登録されていたら、その構造体のpub を1 増やし、登録されていなかった
#  ら、bkcmpy を1つ作成してbkcmpydb に登録する。
#  /*
#  プログラムの引数に書籍データのファイル(c2md.csv) を与える。各出版社が2000 年から2012 年ま
#  でに出版した本の中で最高価格の本の情報を表示せよ。
#  ただし出版社名(name)、書名(book)、発行年(year)、最高価格(price)を表す以下の構造体bkcmpy
#  を用意する。
#  
#  struct bkcmpy {
#  char name[100];
#  char book[420];
#  int year;
#  int price;
#  };
#  
#  各出版社に対して、このbkcmpy を作成し、この構造体の情報を出力することでプログラムを作成せよ。
#  
#  */


'プログラムの引数に書籍データのファイルと列数(a) を与える。書籍データのファイルはc2md.csv である。各行が1つの書籍データを表している。書籍データは出版社名、書名、発行年、本体価格4つの属性を持ち、それらをカンマ(,)で区切って表している。ただし書名にカンマ(,)が含まれる場合には、書名は二重引用符(”)で囲まれている。発行年、本体価格は正の整数値で記述されており、情報がない不明の場合は記述がない。a で指定された列だけを表示せよ。'(_ファイル名,_列数a) :-
        get_lines(_ファイル名,_行ならび),
        書籍データならびに変換する(_行ならび,_書籍データならび),
        空文字でないデータの列数が列数aと一致する情報だけ表示する(_列数a,_書籍データならび).

書籍データならびに変換する([],[]).
書籍データならびに変換する([_行|R1],[[_出版社名,_書名,_発行年,_本体価格]|R2]) :-
        '書籍データは出版社名、書名、発行年、本体価格4つの属性を持ち'(_行,_出版社名,_書名,_発行年,_本体価格),
        書籍データならびに変換する(R1,R2).

'書籍データは出版社名、書名、発行年、本体価格4つの属性を持ち'(_書籍データ,_出版社名,_書名,_発行年,_本体価格) :-
        二重引用符をエスケープに使ったsplit(_書籍データ,[_出版社名,_書名,_発行年,本体価格]).

二重引用符をエスケープに使ったsplit(_書籍データ,L) :-
        atom_chars(_書籍データ,_書籍データ文字ならび),
        二重引用符をエスケープに使った文字ならびを区切る(_書籍データ文字ならび,L).

二重引用符をエスケープに使った文字ならびを区切る([],[]).
二重引用符をエスケープに使った文字ならびを区切る(L1,[A|R2]) :-
        二重引用符にぶつかった(L1,A,R1_2),
        二重引用符をエスケープに使った文字ならびを区切る(R1_2,R2),!.
二重引用符をエスケープに使った文字ならびを区切る(L1,[A|R2]) :-
        カンマ区切りを切り取る(L1,A,R1),
        二重引用符をエスケープに使った文字ならびを区切る(R1,R2).

二重引用符にぶつかった(L1,A,R1_2) :-
        append(L0,['"'|R1],L1),
        \+(member('''',L0)),
        append(L1_1,['"'|R1_2],R1),
        atom_chars(A,L1_1),!.

カンマ区切りを切り取る(L1,A,R1) :-
        append(L0,[','|R1],L1),
        atom_chars(A,L0),!.

空文字でないデータの列数が列数aと一致する情報だけ表示する(_列数a,_書籍データならび) :-
        member(L,_書籍データならび),
        count((member(A,L),\+(A='')),_列数a),
        writef('%t,%t,%t,%t\n',L),
        fail.
空文字でないデータの列数が列数aと一致する情報だけ表示する(_列数a,_書籍データならび).