1

我在一条线上有一串 50 个圣诞灯,当它们第一次插上电源时,所有的灯都熄灭了。灯由单个按钮控制,每次按下按钮时,一些灯会翻转它们的状态(即,如果它们关闭,则变为打开;如果它们打开,则变为关闭)。改变的灯的选择取决于到目前为止按下按钮的次数:

  • 第1次按下,1号、2号、3号、4号、……、50号灯改变状态
  • 第2次按下,第2、4、6、……,灯改变状态;
  • 第3次按下,第3、6、9、……,灯改变状态;
  • 等等
  • 在第 n 次按下时,对应于所有 n 倍数的灯改变状态。

在任何给定数量的“n”次按下后,我如何找出亮着的灯?

我尝试定义一个布尔数组来表示灯光。我写了以下函数:

lightsarray = [False] * 50 ### All lights are off at start ###

def pressbutton(n):
    count = 0

    for count in range(0, n):   
        lightsarray[::int(n)] = [not y for y in lightsarray[::int(n)]]
        count = count + 1
        return lightsarray

目前,n = 1 的输出是True, True, True, True, True, True...

n = 2 的输出为True, False, True, False, True, False...

到目前为止,一切都很好。但是对于 n = 3,我期待True, False, False, False, True, True, True...

但我越来越True, False, False, True, False, False...

我认为我在分配/获取数组状态时出错了。我该如何纠正?还是有更好的方法?

--EDIT-- 感谢大家的回复。我实施了更改,并且得到了您建议的输出,但我不确定这是否与灯的预期状态相匹配。请记住 False = OFF 和 True = ON,让我们看看前 5 个灯。这是预期的:

对于 0 次按下,一切都关闭:

False, False, False, False, False...

按下 1 次,每 1 的倍数处的灯都会翻转:

True, True, True, True, True...

对于 2 次按下,每 2 的倍数处的灯都会翻转:

True, False, True, False, True...

请注意,第二个和第四个灯已切换,否则其余保持不变。

对于 3 次按下,每 3 的倍数处的灯都会翻转:

True, False, False, False, True...

但是,在进行更改后,例如,按 2 次False, True...不给出,按True, False...3 次给出True, True, False, False, False...(开始时有两个 True。)

我该如何纠正?我希望这是有道理的。

4

3 回答 3

1

您的主要问题是您在同一函数中以多种方式使用 count 。本质上,for count in range使用与 相同的变量count=0,并且count = count + 1正在修改循环变量。

另一个问题是您lightsarray每次运行该函数时都在修改全局,因此您的输出将取决于您之前对函数进行排序的方式。

最后,如果你的pressbutton函数应该显示按下按钮n时间的结果,就像它看起来正在做的那样,你应该在每次循环迭代时改变不同的灯光,而不是在每次循环迭代时翻转每个n灯光。

你应该只是在做

def pressbutton(n):
    lightsarray = [False] * 50 ### All lights are off at start ###
    for count in range(0, n):
        lightsarray[::count] = [not y for y in lightsarray[::count]]
    return lightsarray
于 2013-11-11T19:22:16.187 回答
0

你开关了错误的灯;您使用的是循环计数器,n而不是count循环计数器,因此您总是切换错误的灯。

您需要从 1 开始计数,并一直计数到n(因此范围为 `n + 1)。

你的缩进是错误的;你回来得太早了。将return语句取消缩进,使其不属于循环的一部分。

我还将lightsarray值作为函数本身的一部分,不要在此处使用全局变量,因为每次调用函数时它都会发生突变,从而使测试函数本身变得更加困难。

最后但并非最不重要的一点是,无需count手动递增,这就是for循环已经为您做的事情:

def pressbutton(n):
    lightsarray = [False] * 50 ### All lights are off at start ###
    for count in range(1, n + 1):   
        lightsarray[::count] = [not y for y in lightsarray[::count]]
    return lightsarray

现在这可以按预期工作:

>>> pressbutton(1)
[True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]
>>> pressbutton(2)
[False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True]
>>> pressbutton(3)
[True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True, False, False, False, True, True, True]
于 2013-11-11T19:22:31.390 回答
0

如果我理解进程,我会说对于每一步 k,我们首先选择第 k 个元素,然后移动到第 2k 个元素,3k,4k ......

这可以使用 xrange 来实现(我更喜欢 xrange 而不是 range,因为它不会填满内存),它采用 step 参数。

这是这种进展的一个例子

for k in xrange(1, n + 1):
    print range(k, n, k)

应该这样做,这是输出,看起来类似于您的示例:

[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 4, 6, 8]
[3, 6, 9]
[4, 8]
[5]
[6]
[7]
[8]
[9]
[]

注意你不必去 n + 1,你可以停在 n :)

于 2013-11-11T19:19:23.717 回答