このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1364700745/889
#  [1] 授業数学の問題をC言語で解く 
#  [2] 問題 
#  整数xを0から100000までの整数として,xが3つの素数の和で表現できるなら 
#  その三素数を出力するプログラムを作成せよ。複数組み合わせの場合最初に 
#  見つけたものを出力せよ。 
#  [3.1] 7 
#  [3.2] gcc 
#  [3.3] C 
#  [4] 期限:28日9:00 
#  [5] その他制限: 純粋Cライブラリ。 
# 
# 

'整数xを0から100000までの整数として,xが3つの素数の和で表現できるなら
その三素数を出力するプログラムを作成せよ。
複数組み合わせの場合最初に見つけたものを出力せよ。'(_素数_1,_素数_2,_素数_3) :-
        整数を得る(整数x,(_x >= 2,_x =< 100000),_x),
        findall([_素数_1,_素数_2,_素数3],(
                    xが3つの素数の和で表現できる(_x,_素数_1,_素数_2,_素数_3)),
                _3つの素数のならび),
        'その三素数を出力せよ。複数組み合わせの場合最初に見つけたものを出力せよ。'(_x,_3つの素数のならび).


xが3つの素数の和で表現できる(_x,_素数_1,_素数_2,_素数_3) :-
        findall(N,between(2,_x,N),_2から_xまでの整数ならび),
        エラトステネスの篩(_2から_xまでの整数ならび,_2から高々_xまでの素数ならび),
        組合せ(_2から高々_xまでの素数ならび,3,[_素数_1,_素数_2,_素数_3]),
        _x is _素数_1 + _素数_2 + _素数_3.

'その三素数を出力せよ。複数組み合わせの場合最初に見つけたものを出力せよ。'(_x,_3つの素数のならび) :-
        member([_素数_1,_素数_2,_素数_3],_3つの素数のならび),
        'その三素数を出力せよ。'(_x,_素数_1,_素数_2,_素数_3),!.

'その三素数を出力せよ。'(_x,_素数_1,_素数_2,_素数_3) :-
        writef('%t+%t+%t = %t\n',[_素数_1,_素数_2,_素数_3,_x).

エラトステネスの篩([],[]) :- !.
エラトステネスの篩([A|R1],[A|R2]) :-
        エラトステネスの篩(A,R1,L),
        エラトステネスの篩(L,R2).

エラトステネスの篩(_,[],[]) :- !.
エラトステネスの篩(N,[A|R1],R2) :-
        0 is A mod N,
        エラトステネスの篩(N,R1,R2),!.
エラトステネスの篩(N,[A|R1],[A|R2]) :-
        エラトステネスの篩(N,R1,R2).

組合せ(X,1,[A]) :-
        member(A,X).
組合せ([A|Y],N,[A|X]) :-
        N > 1,
        M is N - 1,
        組合せ(Y,M,X).
組合せ([_|Y],N,A) :-
        N > 1,
        組合せ(Y,N,A).


%  整数を得る/3
%  
%  注意
%  
%  ここでは、findall/3を用いて、xが3つの素数の和で表現できる/4の全解を
%  一旦ならびに取得することによって、
%  その後の出力述語を決定性にすることを可能にしている。