소수점 뒤에 양의 정수를 차례대로 붙여 나가면 아래와 같은 무리수를 만들 수 있습니다. 0.123456789101112131415161718192021…. 이 무리수의 소수점 아래 12번째 자리에는 1이 옵니다. 소수점 아래 n번째 숫자를 dn이라고 했을 때, 아래 식의 값은 얼마입니까?
d1 x d10 x d100 x d1,000 x d10,000 x d100,000 x d1,000,000
http://euler.synap.co.kr/prob_detail.php?id=40
접근
문제에서 제시한 소수를 계속 써나가는 규칙은 간단하지만 n번째 숫자를 찾는 방식은 간단하지 않다. 따라서 일반항이 되는 숫자를 바로 구하지 않고 숫자를 하나씩 수집하도록 한다. 이런 건 제너레이터를 이용하면 정말 수월하다.
def gen():
idx, n = 1, 1
while True:
s = str(n)
for c in s:
yield idx, int(c)
idx += 1
n += 1
for i, x in gen():
print(i, x)
if i > 99:
break
문제에서 찾기를 요구하는 항은 순서대로 10k (k = 0, 1, 2, 3, 4, 5, 6)에 해당하는 값이므로, 제너레이터가 만들어내는 값 중 순번이 일치하는 것만 골라서 곱해주면 끝.
%%time
res, g, step, d = 1, gen(), 0, 0
for k in range(7):
while step < 10**k:
step, d = next(g)
res *= d
print(res)