一个基于
你的回答 的解决方案(只是重复你的简化步骤),一个优化版本,击败了 Seon 的版本,以及 Seon 的优化版本。n=65536 时的时间:
2.04 ± 0.03 μs Seon_optimized
2.54 ± 0.04 μs Kelly3_optimized
4.18 ± 0.04 μs Seon
20.51 ± 0.09 μs Kelly3
代码(在线尝试!):
def Kelly3(n):
res = 1
while n:
res *= factorial(n % 5)
n //= 5
res <<= n
return res % 10
def Kelly3_optimized(n):
res = 1
twos = 0
while n:
res *= (1, 1, 2, 6, 24)[n % 5]
n //= 5
twos += n
shift = twos and (twos % 4 or 4)
return (res << shift) % 10
def Seon_optimized(n):
lookup = 1, 1, 2, 6, 4, 2, 2, 4, 2, 8
Lookup = 6, 6, 2, 6, 4, 2, 2, 4, 2, 8, 4, 4, 8, 4, 6, 8, 8, 6, 8, 2
res = 1
while n >= 10:
res *= Lookup[n % 20]
n //= 5
return res * lookup[n] % 10
def Seon(n):
lookup = [1, 1, 2, 6, 4, 2, 2, 4, 2, 8]
if n < 10:
return lookup[n]
if ((n // 10) % 10) % 2 == 0:
return (6 * Seon(n // 5) * lookup[n % 10]) % 10
else:
return (4 * Seon(n // 5) * lookup[n % 10]) % 10
from timeit import timeit
from statistics import mean, stdev
from math import factorial
funcs = Seon, Kelly3, Kelly3_optimized, Seon_optimized
for n in *range(10001), 65536:
expect = str(funcs[0](n))
for f in funcs[1:]:
result = str(f(n))
assert result == expect
times = {f: [] for f in funcs}
def stats(f):
ts = [t * 1e6 for t in sorted(times[f])[:100]]
return f'{mean(ts):6.2f} ± {stdev(ts):4.2f} μs '
for _ in range(1000):
for f in funcs:
t = timeit(lambda: f(65536), number=1)
times[f].append(t)
for f in sorted(funcs, key=stats):
print(stats(f), f.__name__)
n
值?当我尝试使用n=100000
的方法时,几秒钟内就能得到答案。"但我仍然遇到时间限制" - 这是否意味着你正在向别人的测试程序(例如在线测试器)提供代码?在这种情况下,请务必确保你完全理解输入和输出的预期工作方式。可能是因为input
会一直等待,因为测试器不会在 stdin 上提供输入,并且它可能不接受print
的内容作为有效输出。请检查是否应该读取或写入文件。 - Karl Knechtel