关闭灯光算法

时间:2019-03-30 16:10:00

标签: python algorithm

我正在用Python创建TurnOff算法。我想包括数字矩阵。假设有n排灯,编号从1到n,可以在特定条件下打开或关闭。第一个灯可以随时打开或关闭。仅当前面的灯打开且之前的所有其他灯熄灭时,才能打开或关闭其他所有灯。如果最初所有指示灯都点亮,那么如何将它们全部关闭?对于编号为1到3的三个灯,您可以执行以下步骤,其中i表示灯点亮,0表示灯熄灭。

  • 111 3灯亮起
  • 011 ron灯1
  • 010熄灯3
  • 110打开灯1
  • 100个熄灯2
  • 000个关闭灯1

我如何在程序中包括数字矩阵?

到目前为止,这是我的代码:

def turnOff(n):
    #if number of lights is less than one
    if (n < 1):
        return
    #if number of lights is greater or equal to one
    if (n == 1):
        print("Turn off light", n)
    else:
        if(n > 2):
            turnOff(n - 2)
            print("Turn off light", n)
        if(n > 2):
            turnOn(n - 2)
            turnOff(n - 1)


def turnOn(n):
    # if number of lights is less than one
    if(n < 1):
        return
    # if number of lights is 1
    if(n == 1):
        print("Turn on light", n)
    else:
        turnOn(n - 1)
        if(n > 2):
           turnOff(n - 2)
           print("Turn on light", n)
        if(n > 2):
            # call method
            turnOn(n - 2)


def main():
    n = int(input("Please enter a number of lights: "))
    print()
    print(turnOn(n))
    # print("Number of steps", count)


if __name__ == "__main__":
    main()

请输入一些灯光:3

  • 打开灯1
  • 关灯1
  • 打开灯3
  • 打开灯1

这里是我得到的输出。我想添加一个矩阵。

2 个答案:

答案 0 :(得分:0)

您必须创建一个列表变量,以保存灯光状态。当您打开或关闭灯时,将更新列表中的相应条目。您可以使用此列表显示当前状态并验证可以切换的指示灯。

numberOfLights = int(input("Please enter a number of lights: "))
lights         = [1] * numberOfLights
while 1 in lights:    
    lightIndex = int(input(f"{lights} toggle which light ? ")) - 1
    if lightIndex > 0 and lights.index(1) != lightIndex-1:
        print("You cannot toggle that light")
        continue
    lights[lightIndex] = 1 - lights[lightIndex]
print(f"{lights} success !!")

请注意,列表索引从零(不是1)开始。这就是从用户输入的灯号中减去1的原因。

示例游戏:

Please enter a number of lights: 4
[1, 1, 1, 1] toggle which light ? 1
[0, 1, 1, 1] toggle which light ? 2
You cannot toggle that light
[0, 1, 1, 1] toggle which light ? 1
[1, 1, 1, 1] toggle which light ? 2
[1, 0, 1, 1] toggle which light ? 1
[0, 0, 1, 1] toggle which light ? 4
[0, 0, 1, 0] toggle which light ? 2
You cannot toggle that light
[0, 0, 1, 0] toggle which light ? 1
[1, 0, 1, 0] toggle which light ? 2
[1, 1, 1, 0] toggle which light ? 1
[0, 1, 1, 0] toggle which light ? 3
[0, 1, 0, 0] toggle which light ? 1
[1, 1, 0, 0] toggle which light ? 2
[1, 0, 0, 0] toggle which light ? 1
[0, 0, 0, 0] success !!

答案 1 :(得分:0)

考虑用二进制写的数字。观察位随着我们递减的变化,并观察相邻位之间的差异

  x     bits of x     bits of x XORed with adjacent higher bit
 ==   ===========  ===========================================
 15       1111        1000
 14       1110        1001
 13       1101        1011
 12       1100        1010
 11       1011        1110
 10       1010        1111  <--these bits are lights.  Here they are all on
  9       1001        1101
  8       1000        1100
      ... bla bla bla ...
  1       0001        0001
  0       0000        0000

请注意,从最右边的位开始,最后一列位遵循您的规则!

在任何时候,您都有两个选择-您可以翻转第一个光源,或者找到第一个光源并翻转下一个光源。两种选择都对应于x的增减。

G(x)为您将 x 的每一位与第二高位进行异或得到的数字。 (G,因为它是格雷码:https://en.wikipedia.org/wiki/Gray_code

现在,回答有关如何从一个照明序列到另一个照明序列的所有问题变得非常容易。如果要先打开所有灯然后将其关闭,只需:

  • x = 10 开头,这样 G(x)= 15 (二进制为1111)

  • 将其递减为0。这将采取10个步骤。

  • 如果您想知道什么是灯,随时可以写出G(x)