このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1312201995/816
#  [1] 授業単元: プログラミング基礎 
#  [2] 問題文(含コード&リンク):  
#  1〜10の数が書かれたカードが1枚ずつ、全部で10枚あります。 
#  今、これらのカードを並べ、隣り合った数の差を左から次々に加えて 
#  いくことにします。例えば、  
#  2,5,6,8,1,4,3,9,7,10  
#  と並べたならば、  
#  3+1+2+7+3+1+6+2+3=28  
#  ということになります。 
#  この計算結果が最も大きくなるようにカードを並べると、 
#  結果はいくらになるでしょうか。 
#  (注)元の問題は算数の問題なので論理で答えを出すものだが、 
#  ここではプログラムを書いてその最大値を求めて欲しい。  
#   
#  

'1〜10の数が書かれたカードが1枚ずつ、全部で10枚あります。今、これらのカードを並べ、隣り合った数の差を左から次々に加えていくことにします。例えば、 2,5,6,8,1,4,3,9,7,10 と並べたならば、 3+1+2+7+3+1+6+2+3=28 ということになります。この計算結果が最も大きくなるようにカードを並べると、結果はいくらになるでしょうか。'(_カードの差の合計が最大のカードならび,_カード差の合計) :-
        '1〜10の数が書かれたカードが1枚ずつ、全部で10枚あります'(_10枚のカードならび),
        '前後5要素ずつに分割する'(_10枚のカードならび,_前半カードならび,_後半カードならび),
        後半カードならびを反転する(_後半カードならび,_反転した後半カードならび),
        偶数要素を交換する(_前半カードならび,_反転した後半カードならび,_前半カードならび_2,_反転した後半カードならび_2),
        前半部分も反転する(_前半カードならび_2,_反転した前半カードならび_2),
        前半部分と後半部分を結合してカード差の合計が最大のカードならびを完成する(_反転した前半カードならび_2,_反転した後半カードならび_2,_カードの差の合計が最大のカードならび),
        カード差の合計(_カードの差の合計が最大のカードならび,_カード差の合計).
'前後5要素ずつに分割する'(_10枚のカードならび,_前半カードならび,_後半カードならび) :-
        length(_前半のカードならび,5),
        length(_後半のカードならび,5),
        append(_前半のカードならび,_後半のカードならび,_10枚のカードならび).

後半カードならびを反転する(_後半カードならび,_反転した後半カードならび) :-
        reverse(_後半カードならび,_反転した後半カードならび).

偶数要素を交換する([],[],[],[]).
偶数要素を交換する([A,B|R1],[C,D|R2],[A,D|R3],[C,B|R4]) :-
        偶数要素を交換する(R1,R2,R3,R4).

前半部分も反転する(_前半カードならび_2,_反転した前半カードならび_2) :-
        reverse(前半部分も反転する(_前半カードならび_2,_反転した前半カードならび_2).

前半部分と後半部分を結合してカード差の合計が最大のカードならびを完成する(_反転した前半カードならび_2,_反転した後半カードならび_2,_カードの差の合計が最大のカードならび) :-
        append(_反転した前半カードならび_2,_反転した後半カードならび_2,_カードの差の合計が最大のカードならび).

カード差の合計([A,B],S) :-
        S is abs(A-B),!.
カード差の合計([A,B|R1],S) :-
        カード差の合計([B|R1],S1),
        S is abs(A-B)+S1.

%  
%  ここでは算数的解法(これが正しいか疑問ではあるが)の順序を
%  Prologの述語にしてみた。
%  なぜ、この解法で合計が最大になると考えたかについて述語定義の
%  の中で言及できていない。
%  これは致命的な欠陥と言えるのだろう。
%