2014年3月23日日曜日

プロジェクトオイラー Problem 70 「トーティエント関数の置換」 †

Problem 70 「トーティエント関数の置換」 

オイラーのトーティエント関数 φ(n) (ファイ関数とも呼ばれる) とは, n 未満の正の整数で n と互いに素なものの個数を表す. 例えば, 1, 2, 4, 5, 7, 8 は9未満で9と互いに素であるので, φ(9) = 6 となる.
1 は全ての正の整数と互いに素であるとみなされる. よって φ(1) = 1 である.
面白いことに, φ(87109)=79180 であり, 87109は79180を置換したものとなっている.
1 < n < 107 で φ(n) が n を置換したものになっているもののうち, n/φ(n) が最小となる n を求めよ.

http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2070



解法
素数は答えになりません。
nとn-1各桁の数字の個数が絶対合わないからです。

次の候補として
2素因数で1000万に最も近い数が答えの候補となります。
3素因数の場合もあり得ますが確率は大幅に下がります。
そして2素因数で正解が見つかります。


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)).

prime_list(N):-
      between(2000,5000,N),
      is_prime(N).

calc(Primes,[D,P3]):-
      member(P1,Primes),
      member(P2,Primes),
      P1<P2,
      P3 is P1*P2,
      P3<1000*10000,
      P4 is (P1-1)*(P2-1),
      number_codes(P3,List3),
      number_codes(P4,List4),
      msort(List3,List33),
      msort(List4,List33),
      D is P3/P4.

main70:-
        findall(P,prime_list(P),Primes),
      findall(E,calc(Primes,E),AnsList),
      msort(AnsList,[Ans|_]),
      write(Ans)
      .

0 件のコメント:

コメントを投稿