このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1342966104/844
#  [1] 授業単元:C言語  
#  [2] 問題文(含コード&リンク):  
#  http://ime.nu/codepad.org/DXRUGC3J 
#  http://ime.nu/codepad.org/e9CIf3Iy 
#  
#  /*
#  
#  4.
#  2次元平面上の3つの座標 p1、p2、 p3 を頂点とする
#  3角形を考え、構造体 triangle を以下のように定義する。
#  struct triangle {
#  double p1[2]; double p2[2]; double p3[2];
#  };
#  
#  構造体 triangle に対して、以下の関数を作成せよ。 適当な構造体 triangle の変数を
#  いくつか作成して、この関数が正しく動作することを確認するプログラムを作成せよ。
#  
#  int congruence (structure triangle *a, structure triangle *b)
#  
#  三角形 a と三角形 b が合同かどうかを判定する、
#  合同なら 1 を合同でないなら 0 を返す
#  
#  */
#  
#  /*
#  
#  5.構造体Tri は三角形に対応するものであり、3 つの辺の長さ(a,b,c) とその三角形の面積(area) を
#  メンバーとしてして持つ。
#  struct Tri {
#  int a;
#  int b;
#  int c;
#  double area
#  };
#  
#  構造体Tri の変数をランダムにn 個作成して、三角形の面積が大きい順に表示するプログラムを作成
#  する。ただしn はプログラムの引数として与える。また構造体Tri の変数をランダムに作成する際
#  に、a とb には3 以上30 以下の整数をランダムに入れ、c にはa とb の値から、3 辺a, b, c から三
#  角形ができるようにランダムに正の整数を入れる。
#  
#  [実行結果]
#  > ./a.out 1000
#  1 番目に大きい三角形は3 辺が( 30, 29, 41 ) で面積は434.741302
#  2 番目に大きい三角形は3 辺が( 29, 29, 43 ) で面積は418.422260
#  3 番目に大きい三角形は3 辺が( 30, 27, 37 ) で面積は399.749922
#  ...
#  998 番目に大きい三角形は3 辺が( 4, 3, 3 ) で面積は4.472136
#  999 番目に大きい三角形は3 辺が( 3, 3, 3 ) で面積は3.897114
#  1000 番目に大きい三角形は3 辺が( 3, 3, 1 ) で面積は1.479020
#  
#  */

'三角形の面積が大きい順に表示する'(_n) :-
        三角形をn個生成する(_n,_n個の三角形ならび),
        大きい順に表示する(_n個の三角形ならび).

三角形をn個生成する(_n,_n個の三角形ならび) :-
        findall([_a,_b,_c],(
                    between(1,_n,_),
                    三辺の長さを生成する(_a,_b,_c)),
                _n個の三角形ならび).

三辺の長さを生成する(_a,_b,_c) :-
        _a is random(100) + 1,
        _b is random(100) + 1,
        _c is random(100) + 1.


大きい順に表示する(_n個の三角形ならび) :-
        三角形の面積と相対位置のならびを作る(0,_n個の三角形ならび,_面積と相対位置のならび),
        大きい順に(_面積と相対位置のならび,_大きい順に整列した面積と相対位置のならび),
        表示する(0,_大きい順に整列した面積と相対位置のならび,_n個の三角形ならび).

三角形の面積と相対位置のならびを作る(_,[],[]).
三角形の面積と相対位置のならびを作る(N_1,[[_a,_b,_c]|R1],[[_三角形の面積,N_2]|R2]) :-
        N_2 is N + 1,
        ヘロンの公式(_a,_b,_c,_三角形の面積),
        三角形の面積と相対位置のならびを作る(0,R1,R2).

ヘロンの公式(_a,_b,_c,_三角形の面積) :-
        _周囲の半分 is (_a + _b + _c) / 2,
        _三角形の面積 is sqrt(_周囲の半分 * (_周囲の半分 - _a) * (_周囲の半分 - _b) * (_周囲の半分 - _c)).

大きい順に([],[]).
大きい順に([_軸要素|L1],L2) :-
        大きい順に分割する(_軸要素,L1,_軸要素に等しいか大きい要素ならび,_軸要素より小さい要素ならび),
        大きい順に(_軸要素に等しいか大きい要素ならび,_大きい順に整列した軸要素に等しいか大きい要素ならび),
        大きい順に(_軸要素より小さい要素ならび,_大きい順に整列した軸要素より小さい要素ならび),
        append(_大きい順に整列した軸要素に等しいか大きい要素ならび,[_軸要素|_大きい順に整列した軸要素より小さい],L2).

大きい順に分割する(_,[],[],[])).
大きい順に分割する(_軸要素,[_要素|R1],[_要素|_軸要素に等しいか大きい要素ならび],_軸要素より小さい要素ならび) :-
        _要素 @>= _軸要素,
        大きい順に分割する(_軸要素,R1,_軸要素に等しいか大きい要素ならび,_軸要素より小さい要素ならび).
大きい順に分割する(_軸要素,[_要素|R1],_軸要素に等しいか大きい要素ならび,[_要素|_軸要素より小さい要素ならび]) :-
        _要素 @< _軸要素,
        大きい順に分割する(_軸要素,R1,_軸要素に等しいか大きい要素ならび,_軸要素より小さい要素ならび).

表示する(_,[],_).
表示する(_順位_0,[[_面積,_相対番号]|R1],_n個の三角形ならび) :-
        _順位 is _順位_0 + 1,
        nth1(_相対番号,_n個の三角形ならび,[_a,_b,_c]),
        writef('%t 番目に大きい三角形は3 辺が( %t, %t, %t ) で面積は%t\n',[_順位,_a,_b,_c,_面積]),
        表示する(_順位,R1,_n個の三角形ならび).