There is a room with n lights which are turned on initially and 4 buttons on the wall. After performing exactly m unknown operations towards buttons, you need to return how many different kinds of status of the n lights could be.
Suppose n lights are labeled as number [1, 2, 3 ..., n], function of these 4 buttons are given below:
Flip all the lights.
Flip lights with even numbers.
Flip lights with odd numbers.
Flip lights with (3k + 1) numbers, k = 0, 1, 2, ...
Example 1:
Input: n = 1, m = 1.
Output: 2
Explanation: Status can be: [on], [off]
Example 2:
Input: n = 2, m = 1.
Output: 3
Explanation: Status can be: [on, off], [off, on], [off, off]
Example 3:
Input: n = 3, m = 1.
Output: 4
Explanation: Status can be: [off, on, off], [on, off, on], [off, off, off], [off, on, on].
Note:
n and m both fit in range [0, 1000].
class Solution:
     def flipLights(self, n, m):
         """
         :type n: int
         :type m: int
         :rtype: int
         """
         if m == 0:
             return 1
         lights = [True] * n
         if m > 4:
             if m & 1:
                 m = 3
             else:
                 m = 4
         return self.final(m, lights)
         
     def operate(self, num, array):
         if num == 1:
             array = [not i for i in array]
         elif num == 2:
             for i in range(len(array)):
                 if i & 1:
                     array[i] = not array[i]
         elif num == 3:
             for i in range(len(array)):
                 if not i & 1:
                     array[i] = not array[i]
         elif num == 4:
             for i in range(len(array)):
                 if i%3 == 0:
                     array[i] = not array[i]
         return array
 
     def final(self, num, array):
         ops = [[[1] ,[2], [3], [4]],
                [[], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]],
                [[1] ,[2], [3], [4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]],
                [[], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4], [1, 2, 3, 4]]]
         res = []
         for op in ops[num-1]:
             #print(op)
             tmp = array.copy()
             if not op:
                 res.append(tmp)
                 #print('  not op')
             else:
                 #print('  op')
                 for i in op:
                     tmp = self.operate(i, tmp)
                 #print(' ', tmp)
                 if not tmp in res:
                     res.append(tmp)
         return len(res)

class Solution:
     def flipLights(self, n, m):
         """
         :type n: int
         :type m: int
         :rtype: int
         """
         if m == 0:
             return 1
         lights = [True] * n
         if m > 4:
             if m & 1:
                 m = 3
             else:
                 m = 4
         return self.final(m, lights)
         
     def operate(self, num, array):
         if num == 1:
             array = [not i for i in array]
         elif num == 2:
             for i in range(len(array)):
                 if i & 1:
                     array[i] = not array[i]
         elif num == 3:
             for i in range(len(array)):
                 if not i & 1:
                     array[i] = not array[i]
         elif num == 4:
             for i in range(len(array)):
                 if i%3 == 0:
                     array[i] = not array[i]
         return array
 
     def final(self, num, array):
         ops = [[[1] ,[2], [3], [4]],
                [[], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]],
                [[1] ,[2], [3], [4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]],
                [[], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4], [1, 2, 3, 4]]]
         res = []
         for op in ops[num-1]:
             #print(op)
             tmp = array.copy()
             if not op:
                 res.append(tmp)
                 #print('  not op')
             else:
                 #print('  op')
                 for i in op:
                     tmp = self.operate(i, tmp)
                 #print(' ', tmp)
                 if not tmp in res:
                     res.append(tmp)
         return len(res)
