Project Euler 46

久しぶりに解きました。
あんまり良いプログラムではないけど…

Problem 46(日本語)
Problem 46(本家サイト)


%problem 46
:-lib(ic).
solve:-
PrimeMax is 100000,
assert(max(PrimeMax)),
make_list(PrimeMax,Lst),
eratosthenes_sieve(Lst,PrimeLst), % エラトステネスのふるいによる素数列挙

Prime1#::PrimeLst,
Prime2#::PrimeLst,
A#=Prime1*Prime2,
A#=_*2+1, % Aは奇数
indomain(A,min),
(
Prime#::PrimeLst,
B#>0,
(A-Prime)/2 #= B*B,

labeling([B])->
(
% printf(output,"%d = %d + 2*%d^2\n",[A,Prime,B]),
% flush(output)
true
);
(
labeling([Prime1,Prime2]),
printf(output,"answer %d = %d * %d\n",[A,Prime1,Prime2]),
flush(output),
abort
)
),
fail.

mk_lst([],_,[]):-!.
mk_lst([First|Rest],Th,[Rest]):-
First>Th,
mk_lst(Rest,Th,Rest).
mk_lst([First|Rest],Th,[First|Rest]):-
mk_lst(Rest,Th,Rest).

% 2 ~ Idx までのリストを作成
make_list(Idx,List):-
make_list_sub(Idx,List,[]).

make_list_sub(1,Ret,Ret):-!.
make_list_sub(Idx,Ret,List):-
Idx1 is Idx - 1,
make_list_sub(Idx1,Ret,[Idx | List]).

% 素数列挙 エラトステネスのふるい
eratosthenes_sieve([],[]):-!.
eratosthenes_sieve([First | Rest],[First | Rest]):-
max(Max),
First * First > Max ,
!.
eratosthenes_sieve([First | Rest], [First | Ret]):-
erase_baisu(First,Rest,Rest1),
eratosthenes_sieve(Rest1,Ret).

erase_baisu(_,[],[]):-!.
erase_baisu(Base,[First | Rest],[First | Ret]):-
First mod Base =\= 0,
!,
erase_baisu(Base,Rest,Ret).
erase_baisu(Base,[_ | Rest],Ret):-
erase_baisu(Base,Rest,Ret).


実行結果(回答伏せます)
solve.
answer XXXX = XXXX * XXXX
Aborting execution ...

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>