簡體   English   中英

歐拉計划23-無論我做什么,我的回答都太大了

[英]Project Euler 23 - No matter what I do, my answer is far too big

問題23要求所有數字的總和,而不是兩個豐富數字的總和。 我們只需要檢查小於28123的數字。如果整數n的適當除數之和大於n,則整數n是充裕的-12是自1 + 2 + 3 + 4 + 6 = 16> 12以來的第一個整數。最小的數字,它是2個大量數字的總和,因此我們要從總和中排除它。

這是我的python代碼,我嘗試了很多變體,但是使用的是相同的想法:

import math

def divisors_of(n):
    divs=[1]
    for i in range(2,int(math.sqrt(n))+1):
        if i**2 == n:
            divs.append(i)
        elif n%i == 0:
            divs.append(i)
            divs.append(n//i)
    return divs

def is_abun(n):
    return sum(divisors_of(n))>n

numbers=[i for i in range(1,28123)]

for i in numbers:
    for j in range(1,i):
        if is_abun(j) and is_abun(i-j):
         numbers.remove(i)
         break

print(sum(numbers))

想法很簡單,如果j和ij是大量數字,那么j +(ij)= i當然是大量數字的總和,因此我將其從數字列表中刪除。 然后,我總結所有剩余的數字。 我不知道這怎么可能失敗。 但是,結果應該是(從其他來源獲得)4179871,而我總是在197711987的范圍內得到一些東西,它太大了47倍。

我真的不明白這怎么不能產生正確的結果。 必須有一些行不符合我的想法,但是這里的一切對我來說太簡單了,無法懷疑它們。 我以為最可能的錯誤是在計算大量數字時,但是我幾乎完全確定該部分是正確的(如果我按原樣獲取代碼以生成少於28123的大量數字列表,則會得到長度為6965的列表,少於28123 WolframAlpha聲稱的數量)。

問題是您要在迭代列表numbers時對其進行修改。 這導致您刪除的數字少於預期的數字。

您應該遍歷它的一個副本:

for i in list(numbers):
    for j in range(1,i):
        if is_abun(j) and is_abun(i-j):
         numbers.remove(i)
         break

要了解發生了什么,請考慮以下事項:

>>> numbers = list(range(10))
>>> for i in numbers:
...     if i%2 == 0:
...         numbers.remove(i)
...     print(i)
... 
0
2
4
6
8

如您所見, for循環僅對偶數進行迭代。 這是因為上面的for循環大致等同於以下內容:

i = 0
while i < len(numbers):
    number = numbers[i]
    if number % 2 == 0:
        numbers.remove(number)
    print(number)
    i += 1

因此,當您第一次擁有i = 0並因此使number = 0 ,便從numbers刪除了0 ,所以現在您有了numbers = [1,2,3,4,..., 9] 請注意,值1如何在位置0結束的,所以在下一次迭代中,我們有i = 1numbers[1] == [1,2,3,4,...,9][1] == 2跳過了數字1

每次刪除數字時,列表都會被修改,如果此修改導致項目向左移動,則實際上是在跳過它們。 這就是為什么要遍歷列表副本的原因:這樣,對原始列表的修改不會影響迭代過程中“屈服”的數字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM