Python 约瑟夫算法部分成功

Python 约瑟夫算法部分成功,python,algorithm,josephus,Python,Algorithm,Josephus,我的朋友告诉我,在那里你有41个人坐在圆圈里。人号1有一把剑,杀死右边的人,并将剑传给下一个人。这种情况一直持续到只有一个人活着。我用python提出了这个解决方案: print('''There are n people in the circle. You give the knife to one of them, he stabs person on the right and gives the knife to the next person. What

我的朋友告诉我,在那里你有41个人坐在圆圈里。人号
1
有一把剑,杀死右边的人,并将剑传给下一个人。这种情况一直持续到只有一个人活着。我用python提出了这个解决方案:

print('''There are n people in the circle. You give the knife to one of 
       them, he stabs person on the right and
       gives the knife to the next person. What will be the number of whoever
       will be left alive?''')

pplList = []
numOfPeople = int(input('How many people are there in the circle?'))


for i in range(1, (numOfPeople + 1)):
    pplList.append(i)
print(pplList)

while len(pplList) > 1:
    for i in pplList:
        if i % 2 == 0:
            del pplList[::i]
    print(f'The number of person which survived is {pplList[0]+1}')
    break
但它只对42人有效。我应该怎么做,或者我应该如何更改代码以使其适用于,例如,
100、1000
以及圈内更多的人


我查过Josephus问题,看到了不同的解决方案,但我很好奇,经过一些小的调整后,我的答案是否正确,还是应该从头开始。

我看到两个严重的错误

  • 我保证,
    del-ppList[::I]
    不会像您希望的那样做
  • 当你绕圈子时,重要的是要知道你是否杀死了名单中的最后一个人(名单中的第一个人再次死亡)或没有(名单中的第一个人死亡)

  • 与你的断言相反,它对42起作用,它对许多较小的数字不起作用。第一个不起作用的是2。(答案是3而不是1。)

    问题是,如果这个人没有被杀,你最终不会考虑他。例如,如果有9个人,在杀死8个人后,9拥有剑,但你只是从1开始,而不是在下一个循环中的9。正如有人已经提到的那样,它对较小的数字也不起作用。实际上,如果你仔细观察,你在第一个循环中杀死的是奇数,而不是偶数。这是非常错误的

    您可以按如下方式更正代码

    而len(pplList)>1:
    如果len(pplList)%2==0:
    pplList=pplList[::2]#省略每秒钟一个数字
    elif len(pplList)%2==1:
    最后一个不会被杀死
    pplList=pplList[:-2:2]
    pplList.insert(0,last)#将last添加到开始
    

    除此之外,还有很多非常有效的方法来解决这个问题。查看以了解更多信息

    阅读有关如何调试代码的一些提示。您所说的“最多只能对42人使用”是什么意思?当你尝试43次或更多次时,会出现什么错误?那么答案是错误的。我不知道如何为I%2编写条件!=0如果您单击Josephus标记,您将看到带有该标记的所有问题。你会发现许多不同的方法来解决这个问题(以及相关的问题,你不只是想知道谁幸存下来,而是想知道受害者的名单,他们被杀的顺序)。嗨,谢谢你的回复。你说的1是什么意思。?应该是“del pplList[:i]”还是其他什么?第一次迭代结束时,数字索引的变化情况如何?我怎样才能改变那里的状况?我不知道我说的是否清楚。@piotrulu导致这种奇怪操作的通常过程是,“我在寻找一种在我头脑中进行神奇操作的语法。”你的回答“应该是…”是这种说法的延续。相反,请描述您的神奇操作,并将其分解为您可以编写的代码。不管你最后需要1行还是10行,把你的想法分解成更简单的部分。至于它实际做什么。假设在第二次运行时,您在插槽2中看到一个3。然后你将从最开始开始,每三分之一删除一次,这样你就可以从插槽0、3、6、9、12中删除人。。。(请记住,数组从插槽0开始。)如果我这样说的话,恐怕我的Python字典中缺少正确的语法。我对这个问题想得太多了,使它在我的头脑中变得不可能,而实际上它可能是尽可能简单的。你能给我指一下正确的方向吗?例如,如果我选择的带有列表的方法适合此任务?或者你想更改的只有
    del-pplList[::i]
    ?编辑:哦,我在你的第二个帖子之后发布了comment@piotrulu我可以用一百万种方式让这个程序工作。那帮不了你。我们要做的就是把它分解成小而清晰的碎片。非常非常清楚应该发生什么。放入调试语句以确保这一点,并且仅此而已。重复此过程,直到您的小而清晰的片段成为Python函数。