2014年3月18日火曜日

プロジェクトオイラー Problem 49 「素数数列」 †

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 件のコメント:

コメントを投稿