このディレクトリの索引
http://pc12.2ch.net/test/read.cgi/tech/1274827528/686
#  【質問テンプレ】  
#  [1] 授業単元: プログラム実験 
#  [2] 問題文(含コード&リンク): http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10676.txt 
#  
# 
# 【問題1-02】  30点    配列要素の添字参照とポインタによるアドレス参照    [第1-1章  第09,10節]
# 
# int型の配列 arr[] において、添字位置 n1 から n2 までの部分列を逆順にする関数 arr_rev() を考える。
# 例えば、arr = {0,1,2,3,4,5} のとき、2 と 4 の間を逆順にすると、{0,1,4,3,2,5} となる。
# 配列と添字 n1,n2を引数とし、配列要素の添字参照として実装する arr_rev1() と、
# 配列要素のアドレスを与え、ポインタ走査で実装する arr_rev2() の効率性を比較する。
# 後者は、arr_rev2(&arr[n1], &arr[n2]) として呼び出す。
# 
# void arr_rev1(int arr[], int n1, int n2) 
# void arr_rev2(int *p1, int *p2)
# 
# 逆順にする算法自体は、左端と右端の要素を交換を、両端を1つずつ狭めながら繰り返し、範囲が0または1になったら終了する。
# 左右の2つの反復変数を用いる。詳細は、情報数学の教科書や、オンラインのC言語ハンドブックを参照せよ。
# 
# 配列の添字による要素参照  arr[k] は、arrの先頭番地 + 要素型サイズ × k の計算を行っている。
# ポインタ p の移動 p++ とポインタ先の参照 *p の方が直接的で速い。
# 関数の引数においても、arr_rev2() では、起点となる配列の先頭番地 arr が不要となる。
# 有効長の小さい配列で、プログラムの正当性を検証し、有効長を大きくして、計算時間の変化を調べよ。

arr_rev(L1,N1,N2,L2) :-
        N11 is N1 - 1,
        length(L11,N11),
        length(L12,N2),
        append(L12,R,L1),
        append(L11,L13,L12),
        reverse(L13,L14),
        append(L11,L14,R,L2),!.       

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

arr_rev([A|R1],M,N1,N2,[A|R2]) :- M < N1,M2 is M + 1,arr_rev(R1,M2,N1,N2,R2).
arr_rev(L1,N1,N1,N2,L) :-
       arr_rev_p(L1,N1,N2,[],L2,R),
       append(L2,R,L),!.

arr_rev_p(R,M,N2,L,L,R) :- M > N2,!.
arr_rev_p([A|R1],M,N2,L1,L2,R) :-
       M2 is M + 1,
       arr_rev_p(R1,M2,N2,[A|L1],L2,R).