提问人:Fules 提问时间:12/18/2022 最后编辑:Fules 更新时间:12/19/2022 访问量:220
查找具有指定 collatz 序列长度的编号
Finding number with specified collatz sequence length
问:
我需要制作一个程序来查找具有指定 collatz 序列长度的数字。但是,总是存在程序太慢的问题。例如,我目前能得到的最佳分数是 collatz 序列长度为 1200 的数字(我需要能够获得 collatz 序列长度为 1800 的数字)。
我尝试了很多不同的方法,但到目前为止最好的方法是尝试重新创建 collatz 数字树。这是来自 wiki 的示例。正如我之前所说,我需要能够得到一个 collatz 序列长度为 1800 的数字,但我不能得到超过 1200 的数字。
这是我目前的解决方案(我知道这很复杂,但到目前为止我尝试过的其他方法只能使 collatz 序列长度达到 500):
A = int(input())
limit = 1000000000000000000
def runCollaz(ciag):
steps = 0
while ciag != 1:
if (ciag % 2 == 0):
ciag /= 2
else:
ciag *= 3
ciag += 1
steps+=1
return steps
def makeChainLess(number):
if (number % 2 == 0):
return number / 2
else:
return ((number * 3) + 1)
collatzTree = [[1, 1]]
finallAns = "None"
def getAns(collatzTree, what):
awnser = "None"
if (collatzTree[0][0] < limit and collatzTree[0][1] == A):
awnser = collatzTree[0][0]
while (len(collatzTree) > 250):
currentHigh = collatzTree[0][0]
highIndex = 0
index = 0
for x in collatzTree:
if (x[0] > currentHigh):
currentHigh = x[0]
highIndex = index
index += 1
collatzTree.pop(highIndex)
if (collatzTree[0][0] > 4):
if (collatzTree[0][0] - 1) % 3 == 0:
if (collatzTree[0][0] - 1) % 2 != 0:
collatzTree += [[(collatzTree[0][0] - 1) / 3, int(collatzTree[0][1]) + 1]]
collatzTree += [[collatzTree[0][0] * 2, int(collatzTree[0][1]) + 1]]
collatzTree.pop(0)
else:
collatzTree += [[collatzTree[0][0] * 2, int(collatzTree[0][1]) + 1]]
collatzTree.pop(0)
else:
collatzTree += [[collatzTree[0][0] * 2, int(collatzTree[0][1]) + 1]]
collatzTree.pop(0)
if (what == "C"):
return collatzTree
else:
return awnser
while finallAns == "None":
finallAns = getAns(collatzTree, "A")
collatzTree = getAns(collatzTree, "C")
print(int(finallAns))
如果有人能帮忙,我真的会很感激。
答:
0赞
gerald
12/19/2022
#1
这是一个简单的代码,只需几分钟即可运行 1000 万。它只是需要更多的计算能力,这就是 Collatz 的故事。
'''
This code finds numbers that have the specified Collatz sequence length
(by brute force)
'''
import time
start = time.time() #start code timer
n = 1 #set low end of range
for number in range (10000000, n-1, -1): #work down from max range
num = number
trial = 0
while number > 1: #set up looping until 1 is reached
if number % 2 == 0: #set up normal Collatz sequence comp.
number = number // 2
else:
number = (number * 3) + 1
trial = trial+1 #update counter for each loop
if number == 1 and trial == 500 or trial == 600: #set target numbers
#print all numbers where specified target occured:
print("Number with sequence "
"length of {0}: {1}".format(trial, num))
if number == n:
print("end of range") #tells user that code has ended
end = time.time()
print("elapsed time: ",end - start)
评论
0赞
Fules
12/19/2022
恐怕你不明白我的意思。该程序应该在 1800 秒内获得链长度为 10 的数字。我的原始程序能够在不到 10 秒的时间内获得一个 collatz 序列长度为 1400 的数字。所以我担心你的程序比我的原始版本还要慢
0赞
gerald
12/20/2022
对不起,我不知道时间限制非常短。我使用的是 10 年前的 i5 台式机。使用您的代码,我可以在短短几秒钟内得到 1200 的答案,但 1400 对我来说并没有在 10 分钟内完成。但是,你是对的,我的代码甚至比不上你的速度。
0赞
gerald
12/22/2022
这是一个有趣的问题,我注意到如果可以将限制设置得更高,您的代码似乎可以正常工作,正如上面 MattDMo 的评论中所建议的那样。
0赞
Fules
12/23/2022
可悲的是,限制必须精确地是 10^18,但如果你改变 collatz 树长度的限制,它会慢得多
评论
find_length
//3
/3
int()