Automate the Boring Stuff Practice Problem: Collatz Sequence–Running the sequence on the number 1 without going into an infinite loop

huangapple go评论61阅读模式
英文:

Automate the Boring Stuff Practice Problem: Collatz Sequence--Running the sequence on the number 1 without going into an infinite loop

问题

Here's the translated content:

我是一个完全不懂编程的新手,正在尝试使用《用Python来实现枯燥的事情》在线学习Python。我已经查看了所有关于这个问题的其他问题,但没有找到符合我要求的解决方案,所以我将它作为一个新问题提出来。

我一直在解决《ATBS》第3章的问题,最后有一个练习问题,要创建一个程序,该程序将反复执行科拉茨序列(Collatz Sequence)对用户输入的任何正整数进行操作,直到它减少到1为止。科拉茨序列是数学中的一个未解之谜,任何起始数字最终都会减少到1,但没有人能够证明为什么会这样。

无论如何,在科拉茨序列中,如果数字是偶数,则将其除以2。如果数字是奇数,则将其乘以3,然后加1。然后对结果执行相同的操作。所以,如果有人输入5,那么首先变为16(即3*5 + 1)。然后16变成8(即16 / 2),8变成4,4变成2,最后2变成1。

您开始的数字必须是非零整数。负数不起作用,零也不起作用,非整数也不起作用。

我已经编写了几乎完美的代码,但有一个问题。如果用户输入1,它只会将序列视为已完成,而不是像任何其他奇数一样执行序列(即它不会执行这个操作:1*3 + 1变成4,然后4变成2,然后2变成1)。我意识到这可能在技术上是正确的。但我仍然感到困扰,因为我不能弄清楚如何使它以其他方式工作。

如果有人对此有解决方案,我将非常乐意看到。

这是我的代码:

def collatz(myNum):
if myNum % 2 == 0 and myNum > 0: # 偶数的科拉茨操作
print(myNum // 2)
return myNum // 2
elif myNum % 2 != 0 and myNum > 0: # 奇数的科拉茨操作
print(3 * myNum + 1)
return 3 * myNum + 1

while True:
try:
myNum = int(input('请输入一个正整数,但不要是1:'))
incomplete = True # 用于跟踪完成状态的标志变量
while myNum > 1: # 反复操作直到减少到1,并限制输入为正数
myNum = collatz(myNum)
if myNum == 1:
incomplete = False # 设置标志以指示完成
if not incomplete:
quit = input('请输入q退出或输入其他任何键再次执行:')
if quit == 'q': # 允许用户退出或尝试不同的数字
break
except ValueError: # 处理非整数
print('请只输入整数。')


如果我将“while myNum > 1”更改为“while myNum > 0”,则每次运行时都会进入无限循环,不会在减少到1时停止。我可以让它在适当的时候停止,或者我可以让它执行数字1上的序列,但我无法弄清楚如何同时实现这两个目标。

Hope this helps!

英文:

Total programming newbie here, trying to learn python with Automate the Boring Stuff online. I've looked at all the other questions on this problem and haven't found a solution that does what I want, so I am asking it as a new question.

I've been working on a problem from chapter 3 of ATBS, and at the end there is a practice problem to create a program that will repeatedly execute the Collatz Sequence on any positive integer that a user enters, until it reduces to the number 1. The Collatz sequence is an unsolved puzzle in math where any starting number will always end up reducing to 1, but nobody can prove why.

Anyway, in the Collatz sequence, if the number is an even number, you divide by 2. If the number is odd, you multiply by 3 and then add 1. You do the same thing to the resulting output. So, if someone entered 5, that would first become 16 (i.e. 3*5 +1). The 16 then becomes 8 (i.e. 16 / 2), the 8 becomes 4, the 4 becomes 2, and finally the 2 becomes 1.

The number that you start with has to be a non-zero whole number. Negative numbers don't work, zero doesn't work, and non-integers don't work.

I've written code that works almost perfectly, but it has one problem. If the user enters 1, it just treats the sequence as complete instead of treating it like any other odd number and doing the sequence (i.e. it won't do this: 1*3 +1 becomes 4, then 4 becomes 2, then 2 becomes 1). I realize this might be technically correct. But it still bothers me that for the life of me I can't figure out how to make it work the other way.

If anyone has a solution for this, I would love to see it.

Here's my code:

def collatz(myNum):
    if myNum % 2 == 0 and myNum > 0:  # Collatz operation for even numbers
        print(myNum // 2)
        return myNum // 2
    elif myNum % 2 != 0 and myNum > 0:  # Collatz operation for odd numbers
        print(3 * myNum + 1)
        return 3 * myNum + 1

while True:
    try:
        myNum = int(input('Please enter a positive integer other than one: '))
        incomplete = True  # flag variable to track completion
        while myNum  > 1: # repeats until reduces to 1 and constrains input to positive numbers
            myNum = collatz(myNum)
            if myNum == 1:
                incomplete = False  # set flag to indicate completion
        if not incomplete:
            quit = input('Please enter q to quit or any other key to play again: ')
            if quit == 'q': #allows user to exit or try with a different number
                break
    except ValueError: #to deal with non-integers
        print('Integers only please.')

If I change "while myNum > 1" to while myNum > 0, then every time it run, it enters an infinite loop and won't stop once it reduces to 1. I can get it to either stop at the appropriate time, or I can get it to execute the sequence on the number 1, but I can't figure out how to get it to do both.

答案1

得分: 0

首先,让我简要总结一下你的情况。

  • 你的代码能够运行
  • 但你并不满意

让我提到一句著名的话:“如果它能工作,就不要修复它”。


但我理解这是你学习的方式,所以让我来帮忙。
我看到问题在于 collatz 函数从未被调用,因为当 myNum == 1 时,while myNum > 1 条件从未被满足。

为了避免这个问题,你可以简单地使用 while incomplete。因为你之前将 incomplete 声明为 True,并且在Collatz迭代达到1时将其设置为 False,这样应该可以完美工作。

英文:

So first of all, let me recap your situation.

  • Your code works
  • You are not happy

Let me refer to the famous saying "If it works, don't fix it".


But I understand this is your way of learning, so let me help out.
The way I see it, our issue here is that the collatz function is never called because the while myNum > 1 condition is never validated when myNum == 1.

To avoid this, you can simply use while incomplete instead. Since you've declared incomplete as True, beforehand and you set it to False once the Collatz iteration reaches 1. it should work perfectly.

huangapple
  • 本文由 发表于 2023年6月12日 09:43:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76453215.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定