簡體   English   中英

找到數字的最長結果,因此相鄰項是因子或倍數

[英]find longest consequence of numbers so adjacents are factors or multiples

有一個謎題是找到從 1 到 100 的最長數字鏈,以便每個下一個數字都應該是前一個數字的倍數或因數。 每個號碼只能取一次。 我不擅長編程,但它對我來說非常有趣,我花了幾個小時。
我想知道如何使我的代碼更有效。 現在它只能在合理的時間內解決大約 20 個數字。 我想很多時間都花在了 2 個列表復制操作和 .pop(i) 操作上。 謝謝你。 ps 這不是作業。

Output 對於數字=10 是 [4, 8, 1, 5, 10, 2, 6, 3, 9]

qty = 100
max_length = 0
max = []

def main():
    numbers = list(range(1, qty + 1))
    solve([], numbers, 0)
    print(max)

def check_result(result):
    global qty, max_length, max
    if len(result) > max_length:
        max = result
        max_length = len(result)   

def solve(bufer, left, index):
    if index == qty:
        check_result(bufer)

    for i in range(len(left)):
        left_c = left.copy()
        bufer_c = bufer.copy()
        next = left_c.pop(i)

        if index == 0 or next % bufer_c[index - 1] == 0 or bufer_c[index - 1] % next == 0:
            bufer_c.append(next)
            solve(bufer_c, left_c, index + 1)
        else:
            check_result(bufer_c)

if __name__ == "__main__":
    main()

這里沒有深入的見解,只是一些優化——它在大約一分鍾內達到 n = 35。 當前的方法本質上已經是圖形搜索,因此有效地找到最長路徑將變得困難/不可能。

qty=35
max_length = 0
max = []
nr = 0

# precompute factors
factors = [[q for q in range(2, p) if p % q == 0] for p in range(1, qty+1)]

def main():
    numbers = list(range(1, qty + 1))
    left = [True] * qty
    left[0] = False
    solve([1], left, 1)
    print(max)

def check_result(result):
    global qty, max_length, max, nr
    if len(result) > max_length:
        nr += 1
        max = result.copy()
        max_length = len(result)   

def solve(bufer, left, index):
    global max
    if index > max_length:
        check_result(bufer)

    # do the multiples first 
    mult = bufer[index-1]*2
    while mult <= qty:
        if left[mult-1]:
            left[mult-1] = False
            bufer.append(mult)
            solve(bufer, left, index+1)
            bufer.pop()
            left[mult-1] = True
        mult += bufer[index-1]
    
    # then the factors
    for factor in factors[bufer[index-1] - 1]:
        if left[factor-1]:
            left[factor-1] = False
            bufer.append(factor)
            solve(bufer, left, index+1)
            bufer.pop()
            left[factor-1] = True

優化是只檢查前一個元素的倍數和因子,避免復制列表。 剩下的數字列表現在是一個查找表。 我還將起始元素固定為 1 - 一旦找到 1 的“右側”鏈,您可以使用剩余數字找到“左側”的鏈(我沒有實現這個)。

暫無
暫無

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

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