如何更快地使此函数:算法基于偶数和奇数创建链

发布于 2025-01-31 17:00:37 字数 739 浏览 4 评论 0原文

在Python中,我想编写一个函数,该函数返回一个数字集中的数字集,该数字集导致基于计算算法创建的最长序列(“ 如果n甚至除以两个,则乘以两个乘以三个,然后添加一个“)。数字3的Fe,序列将为 3-> 10 - > 5-> 16-> 8-> 4-> 2 - > 1

我尝试编写快速,非幼稚的函数:

def my_fun(n):
    dici = {k: v for k, v in zip(range(n), range(n))}
    count = 0
    while (len(dici)>1):  
       count += 1        
       dici = {k:(v/2 if v%2 == 0 else v*3+1) for k,v in {key: dici[key] for key in dici if dici[key] > 1}.items() }
    while all(value != 1 for value in dici.values()):
       dici = {k:(v/2) for k, v in dici.items()}
       count +=1
    return dici, count

输入10,该功能返回9作为导致最长链的数字(长度19)。

正如我想将功能应用于更多的数字时,此版本在计算上太广泛了。有什么方法可以缩短我的代码?

in Python I would like to write a function that returns the number from a number set that leads to the longest sequence created based on a calculation algorithm ("if n is even divide by two else multiply by three and add one"). F.e. for the number 3, the sequence would be 3-> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1.

My attempt of writing a fast, non naive function:

def my_fun(n):
    dici = {k: v for k, v in zip(range(n), range(n))}
    count = 0
    while (len(dici)>1):  
       count += 1        
       dici = {k:(v/2 if v%2 == 0 else v*3+1) for k,v in {key: dici[key] for key in dici if dici[key] > 1}.items() }
    while all(value != 1 for value in dici.values()):
       dici = {k:(v/2) for k, v in dici.items()}
       count +=1
    return dici, count

With the input of 10, the function returns 9 as the number leading to the longest chain (length 19).

As I would like to apply my function to greater numbers, this version is way too computationally extensive. Is there any way to shorten my code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月下伊人醉 2025-02-07 17:00:37
  • 浮点算术和amp;平等比较很危险:使用//
    (有一个非终止循环的7)
  • 仅除一个启动值时,只要除以两个,
  • 每个参数 s 小于n // 2 ,那里一步是大两倍的两倍:
def ulam(n):
    """ return start, length of the longest sequence starting lower than n. """
    dici = {k: v for k, v in zip(range(n//2, n), range(n//2, n))}
    count = 0
    while dici:  # len(dici)>1):  
        count += 1
        start = next(iter(dici))
        dici = {k:(v//2 if v%2 == 0 else v*3+1) 
                    for k,v in dici.items() if v > 2 }  # > 1 }
        # print(dici, start)
    return start, count

  • floating point arithmetics & comparison for equality is dangerous: use //
    (got a non-ending loop for 7)
  • just dividing by two when just one start value is left may be incorrect
  • For every argument s smaller than n//2, there is one twice as large taking one step more:
    Start with
def ulam(n):
    """ return start, length of the longest sequence starting lower than n. """
    dici = {k: v for k, v in zip(range(n//2, n), range(n//2, n))}
    count = 0
    while dici:  # len(dici)>1):  
        count += 1
        start = next(iter(dici))
        dici = {k:(v//2 if v%2 == 0 else v*3+1) 
                    for k,v in dici.items() if v > 2 }  # > 1 }
        # print(dici, start)
    return start, count

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文