1

我正在尝试解决一个任务,其中有 13 盏灯,从 1 开始,每 5 盏灯关闭一次,当计数达到 13 时,再次从第一项开始。该函数应返回关闭灯的顺序。在这种情况下,对于 13 个项目的列表,返回列表将是[5, 10, 2, 8, 1, 9, 4, 13, 12, 3, 7, 11, 6]。此外,关闭的灯将不再计算在内。

所以我要解决这个问题的方法是创建一个名为 的列表turnedon,它是[1,2,3,4,5,6,7,8,9,10,11,12,13]一个名为的空列表orderoff,每当列表中的灯关闭时,它就会附加到该列表turnedon中。因此,虽然不为空,但如果有意义,则turnedon遍历turnedon列表并附加关闭的灯并turnedoff从列表中删除该灯。turnedon我无法弄清楚应该进入while循环的内容。任何想法都会非常感激。

def orderoff():
    n=13
    turnedon=[]
    for n in range(1,n+1):
        turnedon.append(n)
    orderoff=[]

    while turneon !=[]:
4

3 回答 3

2

这个问题相当于著名的约瑟夫斯问题n囚犯围成一圈,依次被杀,每次下一个被杀的人都是k从前一个人绕圈走几步;台阶只计算在剩余的囚犯之上。可以在Rosetta 代码网站上找到 Python 中的示例解决方案,我在下面稍作调整:

def josephus(n, k):
    p = list(range(1, n+1))
    i = 0
    seq = []
    while p:
        i = (i+k-1) % len(p)
        seq.append(p.pop(i))
    return seq

例子:

>>> josephus(13, 5)
[5, 10, 2, 8, 1, 9, 4, 13, 12, 3, 7, 11, 6]
于 2020-01-16T10:12:19.040 回答
1

我认为更优化的解决方案是使用循环,每次添加位移,并使用模块将数字保持在范围内

def orderoff(lights_num,step):
    turnd_off=[]
    num =0
    for i in range(max):
        num =((num+step-1)%lights_num)+1
        turnd_off.append(num)
    return turnd_off

print(orderoff(13))
于 2020-01-16T09:45:29.050 回答
1

这可行,但结果与您的不同:

>>> pos = 0
>>> result = []
>>> while len(result) < 13 :
...     pos += 5
...     pos %= 13
...     if pos not in result :
...         result.append(pos)
... 
>>> result = [i+1 for i in result]  # make it 1-based, not 0-based
>>> result
[6, 11, 3, 8, 13, 5, 10, 2, 7, 12, 4, 9, 1]
>>>
于 2020-01-16T09:55:46.097 回答