このディレクトリの索引
#  
#  お題:100以下の自然数でふたつの素数の積で表せる数を昇順にすべて表示せよ。
#  

'100以下の自然数でふたつの素数の積で表せる数を昇順にすべて表示せよ。' :-
        '100までの素数をエラトステネスの篩で求める'(_100までの素数ならび),
        '100以下の自然数でふたつの素数の積で表せる数を'(_100までの素数ならび,_ふたつの素数の積で表せる数ならび),
        '昇順にすべて表示せよ。'(_ふたつの素数の積で表せる数ならび).

'100以下の自然数でふたつの素数の積で表せる数を'(_100までの素数ならび,_ふたつの素数の積で表せる数ならび) :-
        findall(_100までの自然数,(
                    '100以下の自然数で'(_100以下の自然数),
                    ふたつの素数の積で表せる数(_100までの自然数,_100までの素数ならび)),
                _ふたつの素数の積で表せる数ならび).

'100以下の自然数で'(_100以下の自然数) :-
        between(1,100,_100以下の自然数).

ふたつの素数の積で表せる数(_100以下の自然数,_100までの素数ならび) :-
        組合せ(_100までの素数ならび,2,[_素数_1,_素数_2]),
        _100以下の自然数 is _素数_1 * _素数_2,!.

'昇順にすべて表示せよ。'(_ふたつの素数の積で表せる数ならび) :-
        sort(_ふたつの素数の積で表せる数ならび,_整列したふたつの素数の積で表せる数ならび),
        atomic_list_concat(_整列したふたつの素数の積で表せる数ならび,' ',_表示文字列),
        writef('%t\n',[_表示文字列]).

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

'100までの素数をエラトステネスの篩で求める'(_100までの素数ならび) :-
        findall(N,between(2,100,N),L),
        エラトステネスの篩(L,_100までの素数ならび).

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

エラトステネスの篩([],[]) :- !.
エラトステネスの篩([A|R1],[A|R2]) :-
        エラトステネスの篩(A,R1,L),
        エラトステネスの篩(L,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).