このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1312201995/940
#  [1] 授業単元:アルゴリズム 
#  [2] 問題文(含コード&リンク): 
#  int型の2次元配列がある。このうち1つの変数に注目したとき、その変数の値と同じ値を持つ変数が 
#  上下左右に何個繋がっているかを返すプログラムを作成せよ。 
#  例えば以下のような配列 int array[8][8];があるとき、 
#  左下の1 (array[7][0])を指定した場合、「1」は5個繋がっていることになる。 
#  その右隣の3 (array[7][1])を指定した場合、「3」は3個繋がっていることになる。 
#   
#  0 2 1 3 0 1 1 2 
#  2 2 2 1 1 2 3 3 
#  3 0 2 1 2 3 2 2 
#  1 1 1 2 1 0 0 1 
#  2 3 3 2 1 0 1 0 
#  2 1 1 2 2 3 0 1 
#  1 1 2 1 2 0 3 1 
#  1 3 3 3 0 0 1 1 
#   
#  

'行列の位置を指定してその位置の値と同じ値が上下左右に何個繋がっているかを返す'(LL,_行位置,_列位置,_度数) :-
        append(L1,[_列|R1],LL),
        length([_|L0],_行位置),
        append(L11,[_値|R11],_列),
        length([_|L11],_列位置),
        上下左右に何個繋がっているか(なし,[L1,[_列|R1]],[L11,[_値|R11]],_度数).

上下左右に何個繋がっているか(_来た方向,[L1,[_列|R1]],[L11,[_値|R11]],_度数) :-
        来た方向を取り除く(_方向,_方向ならび),
        各方向の個数を集計する(_方向ならび,[L1,[_列|R1]],[L11,[_値|R11]],_度数_L),
        length(_度数_L,_度数).

各方向の個数を集計する([],_,_,[]) :- !.
各方向の個数を集計する各方向の個数を集計する([_方向|R],[L1,[_列|R1]],[L11,[_値|R11]],[_|_度数]) :-
        連接する値(_方向,[L1,[_列|R1]],[L11,[_値|R11]],[L2,[_列2|R2]],[L22,[_値|R22]]),
        上下左右に何個繋がっているか(_方向,[L2,[_列2|R2]],[L22,[_値2|R22]],_度数_1),
        各方向の個数を集計する(R,[L1,[_列|R1]],[L11,[_値|R11]],_度数_2),
        append(_度数_1,_度数_2,_度数),!.
各方向の個数を集計する([_|R],[L1,[_列|R1]],[L11,[_値|R11]],_度数) :-
        各方向の個数を集計する(R,[L1,[_列|R1]],[L11,[_値|R11]],_度数).

連接する値(上,[L1,[_列|R1]],[L2,[_値|R2]],[L11,[_上の列|[_列|R11]]],[L22,[_上の値|R22]]) :-
        append(L11,[_上の列],L1),
        length(L2,Len),
        append(L22,[_上の値|R22],_上の列),
        length(L22,Len),!.
連接する値(右,[L1,[_列|R1]],[L2,[_値|R2]],[L1,[_列|R1]],[L22,[_右の値|R22]]) :-
        append(L2,[_値],L22),
        [_右の値|R22] = R2,!.
連接する値(左,[L1,[_列|R1]],[L2,[_値|R2]],[L1,[_列|R1]],[L22,[_左の値|[_値|R2]]]) :-
        append(L22,[_左の値],L2),!.
連接する値(下,[L1,[_列|R1]],[L2,[_値|R2]],[L11,[_下の列|R11]],[L22,[_上の値|R22]]) :-
        length(L2,Len),
        append(L1,[_列],L11),
        [_下の列|R11] = R1,
        append(L22,[_上の値|R22],_下の列),
        length(L22,Len),!.

来た方向を取り除く(上,[上,右,左]) :- !.
来た方向を取り除く(右,[上,右,下]) :- !.
来た方向を取り除く(左,[上,左,下]) :- !.
来た方向を取り除く(下,[右,左,下]) :- !.
来た方向を取り除く(なし,[上,右,左,下]).