Python函数的多种解决方案

Posted

技术标签:

【中文标题】Python函数的多种解决方案【英文标题】:Python multiple solutions for function 【发布时间】:2021-06-21 16:03:29 【问题描述】:

这段代码解决了“猴子椰子”的问题,但我如何修改它以不仅找到初始解决方案,而且继续寻找解决方案?

(编辑)猴椰子问题: 五个人和一只猴子在一个岛上遇难。他们度过了第一个晚上收集椰子。夜里,一个人醒来,决定拿走他那份椰子。他把它们分成五堆。剩下一个椰子,他把它给了猴子,然后把他的那份藏起来,把剩下的放回去,然后继续睡觉。

很快第二个人就醒了,做了同样的事情。把椰子分成五堆,剩下一个椰子给猴子。然后他把他的那份藏起来,把剩下的放回去,然后回到床上。第三个、第四个和第五个男人遵循完全相同的程序。第二天早上,他们都醒了之后,把剩下的椰子分成了五份。这次没有留下任何椰子。

原来那堆椰子有多少?

def solve(sailors):
        nuts = sailors
        while True:
            n0, wakes = nuts, []
            for sailor in range(sailors + 1):
                portion, remainder = divmod(n0, sailors)
                wakes.append((n0, portion, remainder))
                if portion <= 0 or remainder != (1 if sailor != sailors else 0):
                    nuts += 1
                    break
                n0 = n0 - portion - remainder
            else:
                break
        return nuts, wakes

【问题讨论】:

为什么while True 在一次迭代后你总是break 【参考方案1】:

我不是 100%,但我认为这就是你想要的。

首先创建一个解决方案列表,并为您的函数“limit”添加一个新参数。这用于设置退出递归的上限。

找到解决方案后,将其附加到解决方案列表中。

现在检查您的nuts 变量是否超过了您的上限。如果没有,则递归该函数,但从您当前的nuts变量开始,这样就不会再次找到它。

我对猴子椰子问题不是 100%,但这给了我 [11, 23, 47, 95, 191] 的坚果值,水手值 5。

如果这不正确,那么您可能想尝试传递原始水手值并检查它是否在解决方案列表中,如果没有则继续循环。

solutions = []
def solve(sailors, limit):
        nuts = sailors
        while True:
            n0, wakes = nuts, []
            for sailor in range(sailors + 1):
                portion, remainder = divmod(n0, sailors)
                wakes.append((n0, portion, remainder))
                if portion <= 0 or remainder != (1 if sailor != sailors else 0):
                    nuts += 1
                n0 = n0 - portion - remainder
            else:
                break
        solutions.append((nuts, wakes))
        
        if nuts < limit:
            return solve(nuts, limit)
        else:
            return solutions

print(solve(5, 100))

编辑:

好的,我认为上面的解决方案是错误的,但不能确定,因为我不完全理解问题。

现在我将坚果的默认关键字 arg 设置为无。检查它是否为无,如果是,则将其设置为水手。然后在递归上传递它。这使水手的价值保持不变,但每次都会增加坚果

solutions = []
def solve(sailors, limit, nuts=None):
        if not nuts:
            nuts = sailors
        while True:
            n0, wakes = nuts, []
            for sailor in range(sailors + 1):
                portion, remainder = divmod(n0, sailors)
                wakes.append((n0, portion, remainder))
                if portion <= 0 or remainder != (1 if sailor != sailors else 0):
                    nuts += 1
                n0 = n0 - portion - remainder
            else:
                break
        solutions.append((nuts))
        
        if nuts < limit:
            return solve(sailors, limit, nuts=nuts)
        else:
            return solutions

print(solve(5, 100))

这给出了以下结果:

[11, 16, 21, 25, 30, 35, 40, 45, 49, 53, 58, 63, 68, 74, 79, 83, 87, 93, 98, 102]

【讨论】:

谢谢,我试试这个。 没问题,如果它不起作用并且有地方记录了对于某些值的问题的预期解决方案,这就是我会设置测试脚本的那种东西并做TDD。无论哪种方式,我认为解决方案肯定在于递归。 当我执行“print(solve(5,10))”时,它会打印出 (5, 1, 0),然后打印出 (0, 0, 0),但指定了多少次。你知道为什么吗?另外,我只是想在原始堆中找到椰子的解决方案。我拥有的代码可能有点不必要,但数学本身令人困惑。 我真的不确定 tbh 就像你说的那样数学有点混乱,我不完全理解发生了什么,我只是从编程的角度来看它。 (0,0,0) 是我从你的唤醒值中得到的。我已经编辑了我的答案,因为我认为我原来的解决方案是错误的。 如果您只需要坚果值,那么不要像我在第二个解决方案中那样将唤醒添加到解决方案中。

以上是关于Python函数的多种解决方案的主要内容,如果未能解决你的问题,请参考以下文章

python 函数参数多种传递方法

从用mypy注释的python函数返回None,多种返回类型

Win10系统下Anaconda下安装多种Python函数库

用 Python 排序数据的多种方法

R 的 dput() 函数的 Python 等价物

解决python疑难杂症python—文件迭代操作,教你读取文件的多种方法