Problem 69 - オイラーの関数
久しぶりにキマッた。
翻訳無かったけど、オイラーの関数に関する問題。
オイラーの関数φ(n)は、nと互いに素な整数の個数を表す。
例えば、
φ(6) = {1,5} = 2
φ(10) = {1,3,7,9} = 4
n/φ(n)とすれば、nのなかに互いに素な整数の割合がわかる。
φ(n)= n (1 - 1/p_1)(1 - 1/p_2)(1 - 1/p_3)....(1 - 1/p_k)
として求められる。
6の中から2と3で割り切れるものを除いてやると、互いに素の整数1,5だけが残る。
で、今回は100万までのn/φ(n)が一番大きなものを探す。
つまり、互いに素ではない整数の割合が最も多いものを選べばいい。
2の倍数が一番多くの互いに素ではない整数を持つ。
3の倍数が2番目に多くの互いに素ではない整数を持つ。
5の倍数が・・・
素因数分解したら最も多くの素数が取れるもの・・・素数の積を出せばいい。
暗算でもいけちゃうぜ。
(* 2 3 5 7 11 13 17) ; 510510
ハイ。
もうちょっと真面目に。
(define (prime? n) (letrec ((trial-divisor (lambda (t) (or (< n (* t t)) (and (not (zero? (remainder n t))) (trial-divisor (+ t 2))))))) (and (> n 1) (or (= n 2) (and (odd? n) (trial-divisor 3)))))) (define (problem69 n) (letrec ((iter (lambda (m acc) (cond ((> (* acc m) n) acc) ((prime? m) (iter (+ m 2) (* m acc))) (else (iter (+ m 2) acc)))))) (iter 3 2))) (problem69 1000000) ; 510510
普通にやったら100万*素因数分解かかる計算をたった数十回で終わらせることが出来た。
気持ちいい。