Project Euler 230

プロジェクトオイラー
http://projecteuler.net/index.php

Q230.
省略

本当はAかBかをすぐにわかるような関数を数学的に作れればいいが、再帰で簡単に関数が作れるのでまあいいことにする。あとも特に難しいところはない。



def calc_fib_number(n):
k = 1
while F[k] < n:
k += 1
return k

def AB(n, pos):
if n == 1:
return A
elif n == 2:
return B
elif pos < F[n-2]:
return AB(n - 2, pos)
else:
return AB(n - 1, pos - F[n-2])

def D(n):
n -= 1
m = n % 100
n /= 100
k = calc_fib_number(n + 1)
return AB(k, n)[m]

def f(n):
return D((127 + 19 * n) * 7 ** n)

M = 17
N = (127 + 19 * M) * 7 ** M
F = [ 0, 1, 1 ]
while F[-1] < N:
F.append(F[-2] + F[-1])

A = "14159265358979323846264338327950288419716939937510"
A += "58209749445923078164062862089986280348253421170679"
B = "82148086513282306647093844609550582231725359408128"
B += "48111745028410270193852110555964462294895493038196"

print "".join(map(f, range(17, -1, -1)))