✨ 新增 0039、0040 题解及配套文档
This commit is contained in:
91
solutions/0040.ChampernownesConstant/euler_40.py
Normal file
91
solutions/0040.ChampernownesConstant/euler_40.py
Normal file
@@ -0,0 +1,91 @@
|
||||
"""
|
||||
An irrational decimal fraction is created by concatenating the positive integers:
|
||||
0.123456789101112131415161718192021...
|
||||
|
||||
It can be seen that the 12th digit of the fractional part is 1.
|
||||
|
||||
If d_n represents the nth digit of the fractional part, find the value of the following expression.
|
||||
|
||||
d_1 × d_10 × d_100 × d_1000 × d_10000 × d_100000 × d_1000000
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
def timer(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
start_time = time.time()
|
||||
result = func(*args, **kwargs)
|
||||
end_time = time.time()
|
||||
print(f"{func.__name__} time: {end_time - start_time:.6f} seconds")
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
class ChampernownesConstant:
|
||||
def __init__(self):
|
||||
self._cache = "123456789"
|
||||
self._level = 1
|
||||
self._nth = 1
|
||||
|
||||
def __iter__(self):
|
||||
if self._nth > len(self._cache):
|
||||
self._level += 1
|
||||
self._cache += "".join(str(i) for i in range(10**(self._level-1), 10**self._level))
|
||||
yield self._cache[self._nth-1]
|
||||
self._nth += 1
|
||||
|
||||
def __next__(self):
|
||||
return next(self.__iter__())
|
||||
|
||||
def get_nth_digit(self, nth:int) -> int :
|
||||
while True:
|
||||
if nth > len(self._cache):
|
||||
self._level += 1
|
||||
self._cache += "".join(str(i) for i in range(10**(self._level-1), 10**self._level))
|
||||
else:
|
||||
return int(self._cache[nth-1])
|
||||
|
||||
|
||||
@timer
|
||||
def main_longstring() -> None:
|
||||
gen = ChampernownesConstant()
|
||||
ziel = [1,10,100,1000,10000,100000,1000000]
|
||||
res = 1
|
||||
for i in ziel:
|
||||
res *= gen.get_nth_digit(i)
|
||||
print(res)
|
||||
|
||||
|
||||
def length_numbers(k:int) -> int :
|
||||
"""计算前k位数的总位数"""
|
||||
if k == 0:
|
||||
return 0
|
||||
return (10**k * (9*k - 1) + 1) // 9
|
||||
|
||||
|
||||
def get_nth_digit(nth:int) -> int :
|
||||
if nth < 0 :
|
||||
raise ValueError("nth must be non-negative")
|
||||
level = 1
|
||||
while length_numbers(level) < nth :
|
||||
level += 1
|
||||
# 计算在k位数中的偏移量
|
||||
offset = nth - length_numbers(level-1) # 在k位数中的第几个数字
|
||||
num_index = (offset - 1) // level # 第几个k位数(从0开始)
|
||||
num = 10**(level-1) + num_index # 具体的数字
|
||||
digit_index = (offset - 1) % level # 在数字中的位置
|
||||
|
||||
return int(str(num)[digit_index])
|
||||
|
||||
|
||||
@timer
|
||||
def main_quick() -> None :
|
||||
ziel = [1,10,100,1000,10000,100000,1000000]
|
||||
res = 1
|
||||
for i in ziel:
|
||||
res *= get_nth_digit(i)
|
||||
print(res)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main_longstring()
|
||||
main_quick()
|
||||
Reference in New Issue
Block a user