Problem 49 「素数数列」 †
項差3330の等差数列1487, 4817, 8147は次の2つの変わった性質を持つ.
- (i)3つの項はそれぞれ素数である.
- (ii)各項は他の項の置換で表される.
1, 2, 3桁の素数にはこのような性質を持った数列は存在しないが, 4桁の増加列にはもう1つ存在する.
それではこの数列の3つの項を連結した12桁の数を求めよ.
http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2049
解法
4桁昇順の数リストを生成し、それを並び替えたものを作り、重複するものを取り除き、素数であるものだけを素数に変換して素数リストを作り、最後にリストから2つ選び、
3つ目を2つから計算して求め、3つ目が現在の素数リストにあればそれが答えです。
速いかどうかは微妙。
not_prime(N):-N<2,!.
not_prime(N):-
between(2,N,D),
(N<D*D -> !,fail;true),
N mod D=:=0,
!.
is_prime(N):-not(not_prime(N)).
perm(List,D,List):-
length(List,4),
!,
D>48,
number_codes(Num,List),
1000=<Num.
perm(List,D,Result):-
between(D,57,D1),
perm([D1|List],D1,Result).
perm2([],_):-!.
perm2([X|Xs],Nums):-
select(X,Nums,Nums1),
perm2(Xs,Nums1).
prime_list(Nums,P):-
sort(Nums,Nums1),
member(E,Nums1),
number_codes(P,E),
P>1000,
is_prime(P).
perm3([],_):-!.
perm3([X|Xs],Nums):-
select(X,Nums,Nums1),
!,
perm3(Xs,Nums1).
main49:-
findall(E,perm([],48,E),List),
member(E,List),
E1=[_,_,_,_],
findall(E1,perm2(E1,E),List1),
findall(P,prime_list(List1,P),Ps),
select(P1,Ps,Ps1),
select(P2,Ps1,Ps2),
P1<P2,
P3 is P1+2*(P2-P1),
member(P3,Ps2),
write([P1,P2,P3]),
fail.
0 件のコメント:
コメントを投稿