[英]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.