【问题标题】:Loops and Collatz Conjecture循环和 Collat​​z 猜想
【发布时间】:2025-11-23 02:55:01
【问题描述】:

我对循环和声明变量有疑问。目前我正在制作一个关于 Collat​​z 猜想的程序,该程序应该检查从一定数量的 Collat​​z 序列中达到一个最大的步骤是什么。这是我的代码:

start_num = int(input("insert a starting Number > "))
how_many = int(input("how many times you want to check? >"))


def even_or_odd(number):
    if number % 2 == 0:
        return 'isEven'
    else:
        return 'notEven'


def collatz(n):
    z = n
    counter = 0
    while True:
        if n != 1:
            if even_or_odd(n) == 'isEven':
                n = n/2
                counter += 1
                continue
            if even_or_odd(n) == 'notEven':
                n = (n*3)+1
                counter += 1
                continue
        else:
            print('number ' + str(z) + ' reached 1 with : ' + str(counter) + ' steps')
            return counter
            break


def check_biggest_steps(steps_before, steps_after):
    if steps_before > steps_after:
        return steps_before
    if steps_after > steps_before:
        return steps_after
    if steps_after == steps_before:
        return steps_after


def compute_collatz(n_times, collatz_number):
    for _ in range(n_times):
        before = collatz(collatz_number)
        collatz_number += 1
        after = collatz(collatz_number)
        collatz_number += 1
        biggest_steps = check_biggest_steps(before, after)

    print('Biggest Steps is :' + str(biggest_steps))


compute_collatz(how_many, start_num)

这个biggest_steps 变量总是返回最后两个步骤。我知道导致这个问题的原因是 biggest_step 变量位于循环内,但我无法让它在任何地方工作,不知道该怎么做。谢谢

【问题讨论】:

  • 你的even_or_odd 函数相当......好吧,奇怪。将其命名为evenis_even 会更正常,并让它返回TrueFalse,因此调用代码可以执行if is_even(n):。如果你这样做,它是一个单行 - 不需要 if 声明,只需 return not n % 2 - 所以你可能决定取消该功能,而只使用 that collatz 中的条件。同样,您可以将整个check_biggest_steps 函数替换为max(before, after)

标签: python python-3.x loops


【解决方案1】:

在您自己尝试之前不要阅读我的代码。

尝试创建一个列表,将每个更改附加到列表中,然后获取最后的移动次数,只需获取列表的长度即可。

.

def collatz(x):
    while x != 1:
        if x % 2 > 0:
             x =((3 * x) + 1)
             list_.append(x)
        else:
            x = (x / 2)
            list_.append(x)
    return list_


print('Please enter a number: ', end='')
while True:
    try:
        x = int(input())
        list_ = [x]
        break
    except ValueError:
        print('Invaid selection, try again: ', end='')


l = collatz(x)

print('\nList:', l, sep=' ')
print('Number of steps required:', len(l) - 1)

【讨论】:

  • 好吧,我作弊了,看看你的代码。实际上,在我发布这篇文章后,我才想到异常处理(是的,我是在醒来后才写这篇文章的),我什至没有意识到 list 是一个很好的工具。谢谢!
  • 没问题,再看代码,我已经清理了一下。
  • Wtf,这太糟糕了 - OP 有一个好主意,只保留序列的长度 - 只使用 log(len(list_)) 内存。以后使用全局变量会让你很吃力。
  • 这有什么可怕的?它展示了一种思考它并想象它在做什么的方式。你可以只使用一个计数,将它包装在一个函数中。你太迂腐了,它没有进入代码库,他正在学习语言..
【解决方案2】:

你没有保存你的最大步数,并且总是只比较最后 2 个。

我建议进行以下更改。

def compute_collatz(n_times, collatz_number):
    biggest_steps = 0
    for _ in range(n_times):
        steps = collatz(collatz_number)
        if steps > biggest_steps:
            biggest_steps = steps
        collatz_number += 1

    print('Biggest Steps is :' + str(biggest_steps))

【讨论】:

  • 那是错误的。此步骤将使用 collat​​z 编号。