Euler : Problem 69

Posted by TAKAIY On 2011年12月7日水曜日 0 コメント

オイラーのトーシェント関数φ(n)の問題です。


まずは、普通に解いてみましがやっぱり15分もかかります。大きな数の素因数分解そのものに時間がかかるのが問題です。
答が出たので、まあこれでもいいかな...と思っていたのですが、帰りの電車で考えていたら、ひらめきまして、やり直しました。

※ 今回、OpenOfficeの数式エディタで数式を作ってみました。


nの素因数分解が







のようにあらわせるとき、φ(n)は、








で得られます。問題の答は、n/φ(n)を求めます。
最初のやりかたは、ここで、nを素因数分解して、この式をそのまま計算するものでした。

このあと、この式を眺めていて別の方法を思いつきました。

n/φ(n)の値はこういう値です。









nが消えるところがポイントです。
この式の値を大きくするということは、分母を小さくするということです。それには、掛け合わされているかっこの中を小さくすればすればよくて、かっこの中を小さくするには、pを小さくすればいいということがわかります。さらにその数が沢山あればなおいいですね。
ということで、求めるnは、小さな素因数を沢山持つものであることになります。
とはいっても、同じ素因数をいくら持っていても、pは増えませんので、これは、小さい素数から順に素因数として持つものということになります。

ようするに、2、3、5...と、小さいほうから順に1000000を超えないように素数を掛けていくと答が出るということです。
ただ、このやりかただと、重複している素因数がみつからないので、実際にもとめる数はこの数の倍数ということになります。



前半はだめな実装。

- get-n-slash-phi-n
  n/φ(n) を計算する関数
  素因数分解をして、式のとおりに計算しています。

- pe-69
  2からnまでの数について、上の関数を使って、n/φ(n)が最大のものを求める。

下の二つができたやつ。
- product-list
  与えられたコレクションを順に掛けてできる数のリストを返す。
  2 2 2 2 2... なら 2 4 8 16 32... が返ります。

- pe-69
  説明の通りの動作をする関数。
  上の関数で素数を順に掛けた数のリストを作って、引数以下の最大数を求めます。さらに、
  それの倍数で引数以下のものをすべて求めます。


0 コメント:

コメントを投稿