このディレクトリの索引
#  お題: 
#  例:数列[3,1,-7,-1,5]について、 
#  ->[4,-3,-2,3] (累計) 
#  ->12 (絶対値の合計) 
#  のように計算する。 
#  最初の数列の並び順を変えると、最後の合計計も変わる。 
#  任意数列について、上記合計が最小になるように並び替える関数を作成

'例:数列[3,1,-7,-1,5]について、
->[4,-3,-2,3] (累計)
->12 (絶対値の合計)
のように計算する。
任意数列について、上記合計が最小になるように並び替える'(_数列,_最小となる数列) :-
        絶対値の合計が最小になるように並び替える(_数列,_最小となる数列).

絶対値の合計が最小になるように並び替える(_数列,_絶対値が最小となる数列) :-
        length(_数列,_要素数),
        findall([_絶対値の合計,_順列],(
                    順列(_数列,_要素数,_順列),
                    絶対値の合計(_順列,_絶対値の合計)),
                _絶対値_数列ならび),
        絶対値の合計が最小となる数列を得る(_絶対値_数列ならび,_絶対値の合計が最小となる数列).

絶対値の合計(_数列,_絶対値の合計) :-
        数列から累計を得る(_数列,_累計数列),
        絶対値の合計を得る(_累計数列,_絶対値の合計).

数列から累計を得る([_数],_数) :- !.
数列から累計を得る([_数_1,_数_2|R1],[_数_3|R2]) :-
        _数_3 is _数_1 + _数_2,
        数列から累計を得る([_数_3|R1],R2).

絶対値の合計を得る([],0).
絶対値の合計を得る([N|R1],_合計) :-
        絶対値の合計を得る(R1,_合計_2),
        _合計 is abs(N) + _合計_2.

絶対値の合計が最小となる数列を得る(_絶対値_数列ならび,_絶対値の合計が最小となる数列) :-
        findmin(_絶対値,(
                            member([_絶対値,_],_絶対値_数列ならび)),
                _最小の絶対値),
        member([_最小の絶対値,_絶対値の合計が最小となる数列],_絶対値_数列ならび).

順列(_,0,[]).
順列(L1,N,[A|R]) :-
        select(A,L1,R1),
        N_1 is N - 1,
        順列(R1,N_1,R).

findmin(V,P,Min) :-
        findall(V,P,L),
        min(L,Min).