简体   繁体   English

如何找到最小的N

[英]How to find the smallest N

I have a code that determines the survivor from a list of names to walk the plank in this scenario, the last person in the list survives the code i have for this is: 我有一个代码,在这种情况下,它会从一个名称列表中确定幸存者,以便在木板上行走,列表中的最后一个人幸存的代码如下:

names =  ["Andrew", "Brenda", "Craig", "Deidre", "Edward", "Felicity", "Greg", "Harriet"]
def survivor(names, step):
    Next = step - 1
    while len(names) > 1:
        names.pop(Next)
        Next = Next + step
        Next = (Next - 1) % len(names)
        print names

    return names[0]

this works to return the survivor based on what put in step but i also need to work out the smallest N for step for a person to survive eg 3 for greg and 2 for andrew. 这可以根据步调返回幸存者,但我还需要计算最小步长N,以使一个人得以生存,例如,格雷格为3,安德鲁为2。

the codes i have tried for this are: 我为此尝试过的代码是:

assert name in names
for step in survivor(names, step):
    if survivor == name:
        return step

but it keeps saying local variable step referenced before assignment or global step is not defined. 但是它一直说未定义分配或全局步骤之前已引用局部变量步骤。

and

assert name in names
for step in itertools.count(1):
    if survivor(names, step) == name:
        return step

but this returns 但这又回来了

['Brenda', 'Craig', 'Deidre', 'Edward', 'Felicity', 'Greg', 'Harriet'] ['Brenda','Craig','Deidre','Edward','Felicity','Greg','Harriet']

['Craig', 'Deidre', 'Edward', 'Felicity', 'Greg', 'Harriet'] [“克雷格”,“迪德”,“爱德华”,“幸福”,“格雷格”,“哈里特”]

['Deidre', 'Edward', 'Felicity', 'Greg', 'Harriet'] ['Deidre','Edward','Felicity','Greg','Harriet']

['Edward', 'Felicity', 'Greg', 'Harriet'] [“爱德华”,“幸福”,“格雷格”,“哈里特”]

['Felicity', 'Greg', 'Harriet'] ['Felicity','Greg','Harriet']

['Greg', 'Harriet'] ['Greg','Harriet']

['Harriet'] ['Harriet']

which is not what i want 这不是我想要的

Can anyone help me work this out? 谁能帮我解决这个问题?

This loop does not do what you expect. 此循环无法满足您的期望。 What you want should be similar to this: 您想要的应该与此类似:

def shortest(name):
    assert name in names
    for step in range(1, len(names)+1):
        #Go through all possible steps, from 1 to number of items (the +1 is to include the last item too)
        if survivor(names[:], step) == name: # Check that this item matches
            return step # Break out of the loop when you get to it

The itertools.count(1) would work, but you could just as well use a while True and it makes no sense to have a step greater than the length of the names list. itertools.count(1)可以工作,但是您也可以使用while True并且步长大于名称列表的长度没有任何意义。

Your problem was probably with the names array becoming empty after the first name. 您的问题可能是名字数组在名字之后变为空。 Because you are pop ing out all the elements, and modifying the names list which is in the global scope (defined out of the function). 因为要pop所有元素,然后修改全局范围(在函数外部定义)中的names列表。 So you have to duplicate it (using either names[:] or list(names) which will both achieve the same purpose). 因此,您必须复制它(使用将实现相同目的的names[:]list(names) )。

That's the test I made: 那是我做的测试:

for n in names:
    print n, shortest(n)

And the output: 并输出:

Andrew 2
Brenda None
Craig 5
Deidre 7
Edward None
Felicity 4
Greg 3
Harriet 1

Note: I don't know why there are None s in there... but the examples you gave did match! 注意:我不知道为什么那里None ……但是您提供的示例确实匹配!

for step in survivor(names, step):

Notice how you're using step twice here. 请注意您在这里如何使用step两次。 How is Python supposed to pass it to the survivor function before it gets it out of that function? Python应该如何在将其从该函数中删除之前将其传递给survivor函数?

I think what you want is the range function . 认为您想要的是range函数 This will loop through every step value from 1 to the length of the list of names: 这将遍历从1到名称列表长度的每个step值:

for step in range(1, len(names)):

Your itertools.count version should also work, now that I think about it. 现在,考虑到您的itertools.count版本也应该可以使用。 Are you checking the return value of this function or just looking at what it prints out? 您是在检查此函数的返回值还是只是查看它的输出内容? The output looks like it's from this line: 输出看起来像是来自以下行:

print names

One other thing is that your function changes the original list every time it runs, since you change names and you're not making a copy. 另一件事是您的函数每次运行都会更改原始列表,因为您更改了names并且没有进行复制。 Maybe you want to make a copy before changing it: 也许您想在更改之前进行复制:

def survivor(names, step):
    names = names[:]
    # etc

See this question for why names[:] creates a copy of the list. 有关names[:]为什么创建列表的副本的信息,请参见此问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM