Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 计算每个数字的四次方之和,为什么会得到错误的结果?_Python_Math - Fatal编程技术网

Python 计算每个数字的四次方之和,为什么会得到错误的结果?

Python 计算每个数字的四次方之和,为什么会得到错误的结果?,python,math,Python,Math,我正在尝试完成,我决定根据已知答案验证我的代码。基本上,问题是: 求所有可以写成数字五次幂和的数字之和 下面是我试图用python证明的已知答案: 1634=1^4+6^4+3^4+4^4 8208 = 8^4 + 2^4 + 0^4 + 8^4 9474=9^4+4^4+7^4+4^4 因为1=1^4不是一个总和,所以不包括在内 这些数字之和为1634+8208+9474=19316 当我运行我的代码时,我得到了所有三个加起来是19316的值,太棒了!但是,在这些值中有一个不正确的值:6688

我正在尝试完成,我决定根据已知答案验证我的代码。基本上,问题是:

求所有可以写成数字五次幂和的数字之和

下面是我试图用python证明的已知答案:

1634=1^4+6^4+3^4+4^4 8208 = 8^4 + 2^4 + 0^4 + 8^4 9474=9^4+4^4+7^4+4^4

因为1=1^4不是一个总和,所以不包括在内

这些数字之和为1634+8208+9474=19316

当我运行我的代码时,我得到了所有三个加起来是19316的值,太棒了!但是,在这些值中有一个不正确的值:6688

这是我的密码:

i=1
answer = []

while True:
    list = []
    i=i+1
    digits = [int(x) for x in str(i)]

    for x in digits:
        a = x**4
        list.append(a)

        if sum(list) == i:
            print(sum(list))
            answer.append(sum(list))
列表的总和返回三个正确的值和值6688。有人能发现我漏掉了什么吗?

你检查总数太早了。检查数字中每个数字的匹配和,6^4+6^4+8^4等于6688。这是三个数字,不是全部四个

将求和测试移出for循环:

充其量,当总和已经超过目标值时,您可以提前放弃一个数字:

digitsum = 0
for d in digits:
    digitsum += d ** 4
    if digitsum > i:
        break
else:
    if digitsum == i:
        answer.append(i)
但我不想在这里麻烦,只需要使用生成器表达式来组合确定数字,将它们提高到四次方,然后求和:

if sum(int(d) ** 4 for d in str(i)) == i:
    answer.append(i) 
你还没有定义一个上限,即数字总是大于数字之和的点,你需要停止增加i。对于n次幂的和,你可以通过取9^n,计算它的位数,然后取9的n次幂乘以9的n次幂的位数来找到这样一个点。如果这会创建一个位数更多的数字,请继续,直到位数不再更改

同样,你可以从max10开始i,1+2**n,因为你能从数字中得到的最小和将使用一个2位数加上你能逃脱的最小数字1和0,并且在任何大于1的幂次下,除1和0之外的数字的幂次总是大于数字值本身,不能使用i=1:

如果将上述函数与传递给range的range*可变长度参数结合使用,则可以使用for循环:

您可以在函数中设置一个数字是否等于其提升到给定幂n的数字之和:

def is_digit_power_sum(i, n):
    return sum(int(d) ** n for d in str(i)) == i
然后您可以将所有内容放入列表:

>>> n = 4
>>> [i for i in range(*determine_bounds(n)) if is_digit_power_sum(i, n)]
[1634, 8208, 9474]
>>> n = 5
>>> [i for i in range(*determine_bounds(n)) if is_digit_power_sum(i, n)]
[4150, 4151, 54748, 92727, 93084, 194979]
is_digital_power_sum可以从电源缓存中获益;添加缓存可使4位输入的函数速度提高一倍以上:

def is_digit_power_sum(i, n, _cache={}):
    try:
        powers = _cache[n]
    except KeyError:
        powers = _cache[n] = {str(d): d ** n for d in range(10)}
    return sum(powers[d] for d in str(i)) == i
当然,这个问题的答案是这些数字的总和:

n = 5
answer = sum(i for i in range(*determine_bounds(n)) if is_digit_power_sum(i, n))
print(answer)
在我的2.9 GHz Intel Core i7 MacBook Pro上,使用Python 3.8.0a3,在不到半秒钟的时间内产生所需的输出。

您检查总和太早了。检查数字中每个数字的匹配和,6^4+6^4+8^4等于6688。这是三个数字,不是全部四个

将求和测试移出for循环:

充其量,当总和已经超过目标值时,您可以提前放弃一个数字:

digitsum = 0
for d in digits:
    digitsum += d ** 4
    if digitsum > i:
        break
else:
    if digitsum == i:
        answer.append(i)
但我不想在这里麻烦,只需要使用生成器表达式来组合确定数字,将它们提高到四次方,然后求和:

if sum(int(d) ** 4 for d in str(i)) == i:
    answer.append(i) 
你还没有定义一个上限,即数字总是大于数字之和的点,你需要停止增加i。对于n次幂的和,你可以通过取9^n,计算它的位数,然后取9的n次幂乘以9的n次幂的位数来找到这样一个点。如果这会创建一个位数更多的数字,请继续,直到位数不再更改

同样,你可以从max10开始i,1+2**n,因为你能从数字中得到的最小和将使用一个2位数加上你能逃脱的最小数字1和0,并且在任何大于1的幂次下,除1和0之外的数字的幂次总是大于数字值本身,不能使用i=1:

如果将上述函数与传递给range的range*可变长度参数结合使用,则可以使用for循环:

您可以在函数中设置一个数字是否等于其提升到给定幂n的数字之和:

def is_digit_power_sum(i, n):
    return sum(int(d) ** n for d in str(i)) == i
然后您可以将所有内容放入列表:

>>> n = 4
>>> [i for i in range(*determine_bounds(n)) if is_digit_power_sum(i, n)]
[1634, 8208, 9474]
>>> n = 5
>>> [i for i in range(*determine_bounds(n)) if is_digit_power_sum(i, n)]
[4150, 4151, 54748, 92727, 93084, 194979]
is_digital_power_sum可以从电源缓存中获益;添加缓存可使4位输入的函数速度提高一倍以上:

def is_digit_power_sum(i, n, _cache={}):
    try:
        powers = _cache[n]
    except KeyError:
        powers = _cache[n] = {str(d): d ** n for d in range(10)}
    return sum(powers[d] for d in str(i)) == i
当然,这个问题的答案是这些数字的总和:

n = 5
answer = sum(i for i in range(*determine_bounds(n)) if is_digit_power_sum(i, n))
print(answer)
在我的2.9 GHz Intel Core i7 MacBook Pro上,使用Python 3.8.0a3在半秒内产生所需的输出。

此处已修复:

我发现的bug是: 6^4+6^4+8^4 = 6688 所以我只是检查了一下列表的长度。

这里修复了:

我发现的bug是: 6^4+6^4+8^4 = 6688
所以我只是检查一下名单的长度。

旁注:不要使用名单;它掩盖了内置的类型
e、 @MartijnPieters抱歉,我不太明白,你能解释一下这是什么意思吗?Python中内置了一种类型,叫做list。您甚至可以在代码中使用该数据类型。但是,如果使用变量的名称列表,则不能将该名称用于其通常用途。编译器可能会对您的意思感到困惑,而任何阅读您的代码的人肯定会感到困惑。所以不要用这个名字:没有好处。取而代之的是,使用诸如mylist或alist或list1或list of u digits或仅仅是digits之类的名称。@RoryDaulton啊,这很有意义,谢谢帮助方的提示:不要使用名称列表;它屏蔽了内置类型。@MartijnPieters抱歉,我不太明白,你能解释一下这意味着什么吗?Python中内置了一种类型,叫做list。您甚至可以在代码中使用该数据类型。但是,如果使用变量的名称列表,则不能将该名称用于其通常用途。编译器可能会对您的意思感到困惑,而任何阅读您的代码的人肯定会感到困惑。所以不要用这个名字:没有好处。取而代之的是,使用诸如mylist或alist或list1或list of u digits或仅仅是digits之类的名称。@RoryDaulton啊,这很有意义,谢谢你的帮助