このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1294061094/239
#  [1] 授業単元:プログラミング演習  
#  [2] 問題文(含コード&リンク)  
#  縦は無数、横が10列で数字が書き込まれているecxelファイルを読み込む(ファイル名は何でもいいです) 
#  読み込む時は今後の処理を考えてなるべく配列で 
#  その後各列を縦に参照していき、正の値が出たときは別の同じ型の配列の同じ位置に代入していく 
#  負の値が出たときに、そのセルの列の前5個、後ろ5個を参照し以下の処理を行う 
#  前にも後ろにも正の値が検出された場合 → 参照しているセルに一番近い前と後ろの値の2つの平均値を取得し別の配列に格納する 
#  前あるいは後ろの片方にしか正の値が検出されなかった場合 → 一番近い値をそのまま別の配列に格納する 
#  前にも後ろにも正の値が無い場合 → そのままの負の値で別の配列に格納する 
#   
#  最後に値の変更を終えた別の配列をそのままresult.csvとして出力する 
#   
#   
#    

'ファイルからcsvファイルを読み取りルールにしたがってすべてのセルを書き換え、result.csvファイルに出力する'(_ファイル,LL) :-
        '縦は無数、横が10列で数字が書き込まれているecxelファイルを読み込む'(_ファイル,LL1),
        転置(LL1,LL2),
        ルールにしたがってすべてのセルを書き換える(LL2,LL3),
        転置(LL3,LL),
        'result.csvファイルとして出力する'(LL).

'縦は無数、横が10列で数字が書き込まれているecxelファイルを読み込む'(_ファイル,LL) :-
        get_split_lines(_ファイル,[' '],LL).

ルールにしたがってすべてのセルを書き換える(L,[]) :- !.
ルールにしたがってすべてのセルを書き換える([L1|R1],[L2|R2]) :-
        length(L1,Len),
        ルールにしたがってすべての行を書き換える(1,Len,L1,[_セル2|R2]) :-
        ルールにしたがってすべてのセルを書き換える(R1,R2).

ルールにしたがってすべての行を書き換える(M,Len,[]) :- M > Len,!.
ルールにしたがってすべての行を書き換える(M1,Len,L,[_セル1|R2]) :-
        list_nth(M1,L,_セル1),
        _セル1 >= 0,
        M2 is M1 + 1,
        ルールにしたがってすべての行を書き換える(M2,Len,L,R2),!.
ルールにしたがってすべての行を書き換える(M1,Len,L,[_参照しているセルに一番近い値|R2]) :-
        そのセルの列の前5個、後ろ5個を参照し(L,M1,Len,_前5個ならび,_そのセル,_後ろ5個ならび),
        前あるいは後ろの片方にしか正の値が検出されなかった場合(L,_前5個ならび,_そのセル,_後ろ5個ならび),
        '参照しているセルに一番近い値をそのまま別の配列に格納する'(_そのセルの位置,_前5個ならび,_そのセル,_後ろ5個ならび,_参照しているセルに一番近い値),
        M2 is M1 + 1,
        ルールにしたがってすべての行を書き換える(M2,Len,L,R2),!.
ルールにしたがってすべての行を書き換える(M1,Len,L,[_2つの平均値|R2]) :-
        そのセルの列の前5個、後ろ5個を参照し(L,M1,Len,_前5個ならび,_そのセル,_後ろ5個ならび),
        前にも後ろにも正の値が検出された場合(_前5個ならび,_そのセル,_後ろ5個ならび),
        '参照しているセルに一番近い前と後ろの値の2つの平均値を取得し別の配列に格納する'(_前5個ならび,_そのセル,_後ろ5個ならび,_2つの平均値),
        M2 is M1 + 1,
        ルールにしたがってすべての行を書き換える(M2,Len,L,R2),!.
ルールにしたがってすべての行を書き換える(M1,Len,L,[_そのセル|R2]) :-
        そのセルの列の前5個、後ろ5個を参照し(L,M1,Len,_前5個ならび,_そのセル,_後ろ5個ならび),
        前にも後ろにも正の値が無い場合(_前5個ならび,_そのセル,_後ろ5個ならび),
        M2 is M1 + 1,
        ルールにしたがってすべての行を書き換える(M2,Len,L,R2),!.

前あるいは後ろの片方にしか正の値が検出されなかった場合(_前5個ならび,_そのセル,_後ろ5個ならび) :-
        _そのセル < 0,
        append(_,[N1|_],_前5個ならび),
        N1 > 0,
        \+((append(_,[N2|_],_後ろ5個ならび),N2 > 0)),!.
前あるいは後ろの片方にしか正の値が検出されなかった場合(_前5個ならび,_そのセル,_後ろ5個ならび) :-
        _そのセル < 0,
        \+((append(_,[N1|_],_前5個ならび),N1 > 0)),
        append(_,[N2|_],_後ろ5個ならび),
        N2 > 0,!.

前にも後ろにも正の値が検出された場合(_前5個ならび,_そのセル,_後ろ5個ならび) :-
        _そのセル < 0,
        append(_,[N1|_],_前5個ならび),
        N1 > 0,
        append(_,[N2|_],_後ろ5個ならび),
        N2 > 0,!.

前にも後ろにも正の値が無い場合(_前5個ならび,_そのセル,_後ろ5個ならび) :-
        \+((append(_,[N1|_],_前5個ならび),N1 > 0)),
        \+((append(_,[N2|_],_後ろ5個ならび),N2 > 0)),!.

そのセルの列の前5個、後ろ5個を参照し(L,_そのセルの位置,Len,_前5個ならび,_そのセル,_後ろ5個ならび) :-
        Len < _そのセルの位置 + 5,
        _そのセルの位置 >= 6,
        len0 is _そのセルの位置 - 6,
        length(L0,Len0),
        length(_前5個ならび,5),
        append(_前5個ならび,[_そのセル|_後ろ5個ならび],L1),
        append(L0,L1,L),!.

そのセルの列の前5個、後ろ5個を参照し(L,_そのセルの位置,Len,_前5個ならび,_そのセル,_後ろ5個ならび) :-
        _そのセルの位置 < 6,
        Len >= _そのセルの位置 + 5,
        _前5個ならびの長さ is _そのセルの位置 - 1,
        length(_前5個ならび,_前5個ならびの長さ),
        length(_後ろ5個ならび,5),
        append(_前5個ならび,[_そのセル|_後ろ5個ならび],L1),
        append(L1,L2,L),!.
そのセルの列の前5個、後ろ5個を参照し(L,_そのセルの位置,Len,_前5個ならび,_そのセル,_後ろ5個ならび) :-
        _そのセルの位置 >= 6,
        Len >= _そのセルの位置 + 5,
        Len0 is _そのセルの位置 - 6,
        length(L0,Len0),
        length(_前5個ならび,5),
        append(_前5個ならび,[_そのセル|_後ろ5個ならび],L1),
        append(L0,L1,_,L),!.

'参照しているセルに一番近い前と後ろの値の2つの平均値を取得し別の配列に格納する'([],_そのセル,_後ろ5個ならび,_値) :-
        findmin([M,N],(
                    append(_,[N|_],_後5個ならび),
                    M is abs(N - _そのセル)),
                [_差,_値]),!.
'参照しているセルに一番近い前と後ろの値の2つの平均値を取得し別の配列に格納する'(_前5個ならび,_そのセル,[],_値) :-
        findmin([M,N],(
                    append(_,[N|_],_前5個ならび),
                    M is abs(N - _そのセル)),
                [_差,_値]),
'参照しているセルに一番近い前と後ろの値の2つの平均値を取得し別の配列に格納する'(_前5個ならび,_そのセル,_後ろ5個ならび,_2つの平均値) :-
        findmin([M,N],(
                    append(_,[N|_],_前5個ならび),
                    M is abs(N - _そのセル)),
                [_差1,_値1]),
        findmin([M,N],(
                    append(_,[N|_],_後5個ならび),
                    M is abs(N - _そのセル)),
                [_差2,_値2]),
        _2つの平均値 is (_値1 + _値2) / 2.

'参照しているセルに一番近い値をそのまま別の配列に格納する'(_前5個ならび,_そのセル,_後ろ5個ならび,_参照しているセルに一番近い値) :-
        append(_前5個ならび,_後ろ5個ならび,L),
        findmin([M,N],(
                    append(_,[N|_],L),
                    M is abs(N - _そのセル)),
                [_差2,_参照しているセルに一番近い値]),!.

'result.csvファイルとして出力する'(LL) :-
        open('result.csv',write,Outstream),
        'result.csvファイルとして出力する'(Outstream,LL),
        close(Outstream).

'result.csvファイルとして出力する'(_,[]) :- !.
'result.csvファイルとして出力する'(Outstream,[L|R]) :-
        concat_atom(L,' ',S),
        write_formatted(Outstream,'%t\n',[S]),
        'result.csvファイルとして出力する'(Outstream,R).