このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1291471791/972
#  [1] 授業単元: C言語 
#  [2] 問題文(含コード&リンク): 
#  5列5行の多次元配列(0または1が適当に並べられているもの)を用意し 
#  1がある配列の上下左右の配列のうち2または3個1が存在するならその配列を0に変更し 
#  そうでない場合は1のままにする この操作を10回行った配列を求めるプログラムを作成する 
#  またこの配列は上下左右繋がっていて1,1の配列の場合上は1,5、左は5.1である 
#  
%  http://nojiriko.asia/prolog/c144_919.html から述語を借用する。

'5列5行の行列(0または1が適当に並べられているもの)を用意し1があるマスの上下、左右のうち2または3個1が存在するならその行または列を0に変更しそうでない場合は1のままにする。この操作を10回行う'(_ならび) :-
        '5列5行の行列(0または1が適当に並べられているもの)を用意し'(LL1),
        length(Ln,10),
        '1があるマスの上下、左右のうち2または3個1が存在するならその行または列を0に変更しそうでない場合は1のままにするこの操作を10回行う'(Ln,LL1,LL2).

'1があるマスの上下、左右のうち2または3個1が存在するならその行または列を0に変更しそうでない場合は1のままにするこの操作を10回行う'([],LL,LL) :- !.
'1があるマスの上下、左右のうち2または3個1が存在するならその行または列を0に変更しそうでない場合は1のままにするこの操作を10回行う'([_|Ln],LL1,LL) :-
        '1があるマスの上下、左右のうち2または3個1が存在するならその行または列を0に変更しそうでない場合は1のままにする'(LL1,LL2),
        '1があるマスの上下、左右のうち2または3個1が存在するならその行または列を0に変更しそうでない場合は1のままにするこの操作を10回行う'(Ln,LL2,LL).

'1があるマスの上下、左右のうち2または3個1が存在するならその行または列を0に変更しそうでない場合は1のままにする'(LL1,LL2) :-
        length(LL2,5),
        findall(_マス目の値2,(
                    length(Line,5),
                    append(L00,[Line|_],LL2),
                    append(L01,[_マス目の値2|_],Line),
                    length(L00,_行の一),
                    length(L01,_列の一),
                    _行 is _行の一 + 1,
                    _列 is _列の一 + 1,
                    マス目の周囲(LL1,_行,_列,_マス目の値1,_マス目の周辺),                    
                    マス目の状態診断(_マス目の値1,_マス目の周辺,_マス目の値2)),
                LL2).

'5列5行の行列(0または1が適当に並べられているもの)を用意し'(LL) :-
        length(LL,5),
        findall(L,(
                    length(L,5),
                    append(_,[A|_],L),
                    A is random 2),
                LL).

マス目の周囲(LL,1,_マス目の列,_マス目の値,_マス目の周辺ならび) :-
        append(LL0,[L],LL),
        append(LL,[L],LL1),
        マス目の周囲(LL,2,_マス目の列,_マス目の値,_マス目の周辺ならび),!.
マス目の周囲(LL,5,_マス目の列,_マス目の値,_マス目の周辺ならび) :-
        LL = [L1|R],
        append(R,L1,LL2),
        マス目の周囲(LL,4,_マス目の列,_マス目の値,_マス目の周辺ならび),!.
マス目の周囲(LL,_マス目の行,_マス目の列,_マス目の値,_マス目の周辺ならび) :-
        _マス目の行 >= 2,
        _マス目の行 =< 4,
        Nth1 is _マス目の行 - 2,
        length(L0,Nth1),
        append(L0,[Line1,Line2,Line3|_],LL),
        マス目の周囲([Line1,Line2,Line3],_マス目の列,_マス目の値,_マス目の周辺ならび),!.

マス目の周囲([Line1,Line2,Line3],1,_マス目の値,_マス目の周辺ならび),!.
        length(L0,4),
        findall(L,(
                    append(_,[Line|_],[Line1,Line2,Line3]),
                    append(L0,L1,Line),
                    append(L1,L0,L)),
                LL),
        マス目の周囲(Line1,Line2,Line3,2,_マス目の値,_マス目の周辺ならび),!.
マス目の周囲([Line1,Line2,Line3],5,_マス目の値,_マス目の周辺ならび) :-
        length(L1,4),
        findall(L,(
                    append(_,[Line|_],[Line1,Line2,Line3]),
                    append(L0,L1,Line),
                    append(L1,L0,L)),
                LL),
        マス目の周囲(Line1,Line2,Line3,4,_マス目の値,_マス目の周辺ならび),!.
マス目の周囲([Line1,Line2,Line3],_マス目の列,_マス目の値,[A2,A4,A6,A8]) :-
        _マス目の列 >= 2,
        _マス目の列 =< 4,
        Nth1 is _マス目の列 - 2,
        length(L0,Nth1),
        findall(U,(
                    append(_,[Line|_],[Line1,Line2,Line3]),
                    append(L0,[A,B,C|_],Line),
                    append(_,[U|_],[A,B,C])),
                L),
        L = [A1,A2,A3,A4,_マス目の値,A6,A7,A8,A9],!.

マス目の状態診断(_マス目の値,_マス目の周囲,0) :-
        '1のマス目の周囲に2つか3つの1のマス目があれば0に変更される'(_マス目の値,_マス目の周囲,'0'),!.
マス目の状態診断(_マス目の値,_マス目の周囲,_マス目の値).

'1のマス目の周囲に2つか3つの1のマス目があれば0に変更される'(1,_マス目の周囲) :-
        count((append(_,[1|_],_マス目の周囲),Count),
        Count >= 2,
        Count =< 3,!.