Project Euler 80: Square root digital expansion

Posted metaquant

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Project Euler 80: Square root digital expansion相关的知识,希望对你有一定的参考价值。

众所周知如果一个整数的平方根不是一个整数,那么这个平方根就是一个无理数,这种平方根的小数表示是无限不循环的。二的平方根是(1.41421356237309504880...),它的前一百位数字的和是475。对于前一百个自然数,如果它的平方根是无理数,求这些无理数的小数表示的前一百之和的和。

分析:计算平方根的方法有很多,如经典的牛顿迭代法,但这些方法都会使用浮点数,从而容易出现近似误差的问题,在求小数表示的数位之和时容易出现错误。经过查阅资料,在这篇论文中我发现一个非常简单易懂的计算任意精度的平方根的方法,这种方法虽然收敛速度要慢于牛顿迭代法,但最大的优点是只需要通过整数的加减就可以得到答案,从而完全避免浮点误差问题。对算法的具体介绍和背后的原理大家可以参见论文,我这里只简单描述以下算法的实现步骤:

  • 要求非完全平方数(n)的平方根前(p)位有效数字之和,则设(a=5n,b=5)
    • 如果(age b),则(a-b ightarrow a,b+10 ightarrow b)
    • 如果(a<b),则(100a ightarrow a),并在(b)的个位数加上零构成一个新数再赋值给(b)
    • 如上一直循环,直到(b)的位数达到(p)位(实际中为了避免误差,会再多求两三位);
  • 循环结束后返回(b)的前(p)位数数位之和,即为题目所求。

对于前一百个自然数中的非完全平方数,依次求其小数表示的前一百个有效数字之和,然后把这些和加总起来,即为题目所求,代码如下:

# time cost = 42.1 ms ± 549 μs

def jarvis_sqrt_sum(n,prec=100):
    a,b = 5*n,5
    while len(str(b)) <= prec+3:
        if a >= b:
            a,b = a-b,b+10
        else:
            a,b = a*100,(b-b%10)*10+b%10
    return sum([int(x) for x in str(b)[:prec]])

def main():
    numbers = set(range(2,100))-{x**2 for x in range(2,10)}
    ans = 0
    for i in numbers:
        ans += jarvis_sqrt_sum(i)
    return ans

以上是关于Project Euler 80: Square root digital expansion的主要内容,如果未能解决你的问题,请参考以下文章

Project Euler:Problem 61 Cyclical figurate numbers

Project-Euler (Make/Source) 的有用文件夹结构? [关闭]

Project Euler 109 :Darts 飞镖

Project Euler 5

Project Euler

project euler 169