在我说别的之前 - 这个问题可能看起来很长,但实际上它只是核心中的一个问题,这种问题会重复出现。我正在尝试创建一个与概率有关的“解谜器”。这是一个模型,解决问题的人必须在没有计算机帮助的情况下完成,但我希望能够拥有一个脚本,我可以在其中更改不同条件下的变量。我们将这个测试用于潜在员工,我们必须想出答案。这很乏味,所以我希望有人可以帮助我尝试在 Python 中做到这一点?我仍在学习 Python,但因为我看到每个人都可以轻松地“操纵”它来为他们提供所需的东西,所以我希望学习如何做到这一点,所以我不必一遍又一遍地手动完成。
这是测试的一个例子 -
鉴于事实:
- 一排有5间房子,从左到右依次编号为1、2、3、4、5。
- 每栋房子都涂有不同的颜色:红色、橙色、黄色、绿色或蓝色。
- 每所房子由不同的人拥有:Ann、Bob、Carl、Dorothy 或 Ed。
- 每栋房子都有不同数量的窗户:一、二、三、四、五
- 每栋房屋建于不同的年份:1970 年、1980 年、1990 年、2000 年或 2010 年。
- 每个人都懂不同的语言:西班牙语、法语、拉丁语、德语、意大利语。
然后我们给他们约束:
- 鲍勃住在黄色的房子里。
- 安懂拉丁语。
- 橙色的房子有5扇窗户。
- 多萝西住在一个有两扇窗户的房子里。
- 橙色的房子就在温室的右边。
- 这位讲德语的人住在这座建于 2000 年的房子里。
- 红房子建于1970年。
- 中间的房子有3个窗户。
- 卡尔住在第一所房子里。
- 这座建于 1980 年的房子紧挨着这位意大利演讲者的房子。
- 这座建于 1970 年的房子毗邻这位说法语的人居住的房子。
- 建于 1990 年的房子有 1 个窗户。
- Ed住在一栋建于2010年的房子里。
- 卡尔住在蓝房子旁边。
潜在员工必须弄清楚:
对于编号为 1 到 5 的每栋房子,住在那里的人、房子是什么颜色、有多少窗户、什么时候建造的以及居住者说什么语言。这正是我想要放入 Python 的内容!
我试了一下,这是我的理由:
def permutations(x):
outlist = []
for a in x:
for b in x:
if b == a:
continue
for c in x:
if c == b or c == a:
continue
for d in x:
if d == a or d == b or d == c:
continue
for e in x:
if e == a or e==b or e==c or e==d:
continue
outlist.append([a,b,c,d,e])
return outlist
循环中的“检查”是为了在重复条目时循环继续,因此除非早期循环有效,否则内部循环不必执行 - 节省时间!
给定一个包含五个元素的列表 x,此函数返回一个列表列表,每个列表都是原始五个元素的排列,其中没有一个元素等于另一个。因此,如果列表输入是 x = [1,2,3,4,5],则返回的输出是一个可能排列的列表:
Outlist = [[1,2,3,4,5],[1,2,3,5,4],[1,2,4,3,5],[1,2,4,5,3], ...]
这将有 5 个!= 120 个元素。
所以,我知道它在理论上是如何工作的,但是用 Python 写下来对我来说“翻译”非常重要。
我将名称变量 (Ann,Bob,Carl,Dorothy,Ed) 指定为这些排列之一(例如 [1,2,5,4,3]),这意味着 Ann 住在 1 号房子里,Bob 住在 2 号房子里, Carol 住在 5 号屋,Dorothy 住在 4 号屋,Ed 住在 3 号屋。
同样,我知道您可以将这些排列中的另一个(例如 [5,4,3,1,2])分配给颜色变量(红、橙、黄、绿、蓝),这意味着房子 5 是红色,房子 4橙色,3 号房屋为黄色,1 号房屋为绿色,2 号房屋为蓝色。
您可以为窗户数量(一、二、三、四、五)、房屋建造年份(七、八、九、零、十)和所用语言分配相同或另一种排列。
这就是我真正迷失的地方,因为我很难理解如何重复使用相同的数字——在这种情况下它们不会被覆盖吗?
不过,首先要做的是——如果我们首先检查这个任务的线索是否正确,会更好(更省时)。如果没有,参加考试的人可以去另一个作业!
编码方面,这就是我的想象,但我对 Python 的有限知识并没有真正帮助我编写“正确的代码”:
a) check if Bob lives in the yellow house, by Bob == Yellow
(即分配给 Bob 的门牌号与分配给 Yellow 的门牌号相同。b)检查 1970 年建造的房子是否与说法语的人住的房子相邻,做绝对值计算 ->
abs(Seven – French) == 1
这意味着分配给七号和法文的门牌号仅相差 1。
此外,我知道还有额外的检查,并且所有这些检查都必须作为 True 传递,五个排列分配才能成为难题的解决方案。
然后我使用循环将排列分配给变量:
for a in outlist:
(Ann,Bob,Carl,Dorothy,Ed) = a
它将给 Ann 赋值 a[0],Bob 赋值 a[1],Carol 赋值 a[2],Dorothy 赋值 a[3],Ed 赋值 a[4],因为我们循环遍历所有排列在 outlist 中,其中 outlist 是函数的输出,是排列列表的列表。
另一个问题 - 列出清单......显示有点困难。
我知道我必须为感兴趣的变量编写五个嵌套的赋值循环。为了验证分配是否满足线索,我考虑在完成部分分配后在每个循环中逐步检查线索的子集,因此除非线索子集得到满足,否则我不会枚举内部循环。同样,它使程序运行得更快、更有效。
这是第一个循环的尝试,它(例如)在名称上。我知道 Carl 必须住在 1 号房子里,如果这不是真的,其他循环不会被执行!在纸面上,你必须不断重复这个过程,直到 Carl == 1!
尝试编写代码:
for a in outlist:
(Ann,Bob,Carl,Dorothy,Ed) = a
if Carl != 1:
continue
for b in outlist:
(Red,Orange,Yellow,Green,Blue) = b
if ...
使用此代码,内部四个循环仅在 Carl == 1 时执行。我知道我必须继续,但变量的重叠在这里也是一个问题。
最后 - 有人建议我使用时间模块“计时功能”
time.time().
我知道在 Mac(所以我的)中报告的当前时间是以微秒为单位的,这是根据那个写的。不知道如何获得正确的代码。
import time
start = time.time()
#CODE
end = time.time()
print('Running Time: {} msecs'.format((end - start)*0.001))
感谢您完成此任务!我发现它非常压倒性,不知道从哪里开始,但我肯定希望有这样的东西为我做我所有的排列!