http://projecteuler.net/index.php?section=problems&id=133
素数pでR(10n)が割り切れるということは、A(p)でR(10n)が割り切れるということです。そのようなnが存在するということは、A(p)は2か5以外の因子を含まないということです。
from itertools import * from fractions import gcd def div_pow(n, p): e = 0 while n % p == 0: e += 1 n /= p return e, n def factorize(max_n): a = range(max_n + 1) b = [ () for n in a ] for p in takewhile(lambda p: p * p <= max_n, ifilter(lambda n: a[n] == n, xrange(2, max_n + 1))): for n in xrange(p * 2, max_n + 1, p): e, a[n] = div_pow(a[n], p) b[n] = b[n] + ((p, e),) for n in ifilter(lambda n: a[n] > 1, xrange(2, max_n + 1)): b[n] = b[n] + ((a[n], 1),) return b def value_f(f): return reduce(lambda x, y: x * y[0] ** y[1], f, 1) def gen_divisors(f, k = 0): if k == len(f): yield 1 else: p, e0 = f[k] for n in gen_divisors(f, k + 1): yield n for e in range(1, e0): yield p ** e * n yield p ** e0 * n def get_exp(n, p): return 0 if n % p != 0 else 1 + get_exp(n / p, p) def A(n): f = fs[n-1] for d in sorted(list(gen_divisors(f))): if pow(10, d, n) == 1: e3 = get_exp(n, 3) - get_exp(d, 3) if e3 > 0: return d * 3 ** e3 else: return d def is_prime(n): f = fs[n] return len(f) == 1 and f[0][1] == 1 def is_valid(n): def g(f): if len(f) == 0: return True p = f[0][0] if p == 2 or p == 5: return g(f[1:]) else: return False if gcd(n, 30) != 1: return False return g(fs[A(n)]) N = 10 ** 5 fs = factorize(N - 1) print sum(n for n in xrange(2, N) if is_prime(n) and not is_valid(n))