#!/usr/bin/env python
#-*- coding:utf-8 -*-
import operator
def combinations_with_replacement(iterable, r):
pool = tuple(iterable)
n = len(pool)
if not n and r:
return
indices = [0] * r
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != n - 1:
break
else:
return
indices[i:] = [indices[i] + 1] * (r - i)
yield tuple(pool[i] for i in indices)
def factors(n):
l = []
if n % 2 == 0:
l.append(2)
while n % 2 == 0:
n /= 2
i = 3
while n > 1:
if n % i == 0:
l.append(i)
while n % i == 0:
n /= i
i += 2
return l
def phi(n):
f = factors(n)
p = n
for factor in f:
p = p * (factor - 1) / float(factor)
return p
def gen_primes():
D = {}
q = 2
while True:
if q not in D:
yield q
D[q * q] = [q]
else:
for p in D[q]:
D.setdefault(p + q, []).append(p)
del D[q]
q += 1
def r(d):
d = float(d)
return (1.0 / (d-1)) * phi(int(d))
def solve(limit = (15499.0 / 94744.0)):
primes = gen_primes()
rr = 1.0
prime = primes.next()
pl = [ prime ]
while rr >= limit:
prime = primes.next()
pl.append(prime)
tmp = r( reduce(operator.mul, pl) )
rr = tmp
pl.pop()
additionals = []
for i in range(1, len(pl)):
for a in combinations_with_replacement(pl, i):
m = reduce(operator.mul, a)
if m not in additionals:
additionals.append(m)
additionals.sort()
for m in additionals:
d = reduce(operator.mul, pl) * m
if r(d) < limit:
print 'Answer: %s' % d
return
if __name__ == '__main__':
solve()
Project Euler P.243
$R(d) < \dfrac{\phi(d)}{d}$ 임을 이용해서 $ \dfrac{\phi(d_1)}{d_1} < R(d) < \dfrac{15499}{94744} < \dfrac {\phi(d_2)}{d_2} $ 인 $d_1$을 찾고 $d_1 < d < d_2$ 를 이용해서 $d$를 찾는다.
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기