There is a room with n bulbs labeled from 1 to n that all are turned on initially, and four buttons on the wall. Each of the four buttons has a different functionality where:
2, 4, ...).1, 3, ...).j = 3k + 1 where k = 0, 1, 2, ... (i.e., 1, 4, 7, 10, ...).You must make exactly presses button presses in total. For each press, you may pick any of the four buttons to press.
Given the two integers n and presses, return the number of different possible statuses after performing all presses button presses.
Example 1:
Input: n = 1, presses = 1 Output: 2 Explanation: Status can be: - [off] by pressing button 1 - [on] by pressing button 2
Example 2:
Input: n = 2, presses = 1 Output: 3 Explanation: Status can be: - [off, off] by pressing button 1 - [on, off] by pressing button 2 - [off, on] by pressing button 3
Example 3:
Input: n = 3, presses = 1 Output: 4 Explanation: Status can be: - [off, off, off] by pressing button 1 - [off, on, off] by pressing button 2 - [on, off, on] by pressing button 3 - [off, on, on] by pressing button 4
Constraints:
1 <= n <= 10000 <= presses <= 1000When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach for the bulb switcher problem involves trying every possible combination of button presses. We'll explore all the different sequences of button presses and see how they affect the lights. The goal is to count how many distinct final states of the lights are possible.
Here's how the algorithm would work step-by-step:
def flip_lights_brute_force(number_of_bulbs, number_of_presses):
possible_states = set()
for i in range(1 << (number_of_presses * 1)):
# Generate all possible combinations of button presses
button_presses = []
for j in range(number_of_presses):
if (i >> j) & 1:
button_presses.append(1)
else:
button_presses.append(0)
bulbs = [1] * number_of_bulbs
# Simulate the effect of pressing the buttons
for k in range(number_of_presses):
if button_presses[k]:
if k == 0:
for index in range(number_of_bulbs):
bulbs[index] = 1 - bulbs[index]
elif k == 1:
for index in range(0, number_of_bulbs, 2):
bulbs[index] = 1 - bulbs[index]
elif k == 2:
for index in range(1, number_of_bulbs, 2):
bulbs[index] = 1 - bulbs[index]
else:
for index in range(0, number_of_bulbs, 3):
bulbs[index] = 1 - bulbs[index]
# Record the final state of the bulbs as a tuple
possible_states.add(tuple(bulbs))
# Remove any duplicate bulb states, then return the result
return len(possible_states)The trick to solving this problem efficiently is to realize that the number of bulbs and button presses don't matter as much as they seem. There are only a limited number of different states you can reach, so we can figure out what all the possible final configurations of the bulbs are without testing every single combination.
Here's how the algorithm would work step-by-step:
def bulb_switcher_ii(number_of_bulbs, number_of_presses):
if number_of_presses == 0:
return 1
if number_of_bulbs == 1:
return 2
if number_of_bulbs == 2:
if number_of_presses == 1:
return 3
else:
return 4
if number_of_bulbs >= 3:
if number_of_presses == 1:
return 4
elif number_of_presses == 2:
return 7
else:
return 8
def bulb_switcher_ii_detailed(number_of_bulbs, number_of_presses):
# Handle edge cases where the solution is trivial
if number_of_presses == 0:
return 1
possible_states = set()
# Iterate through all possible combinations of button presses
for first_button in range(2 if number_of_presses > 0 else 1):
for second_button in range(2 if number_of_presses > 0 else 1):
for third_button in range(2 if number_of_presses > 0 else 1):
for fourth_button in range(2 if number_of_presses > 0 else 1):
if sum([first_button, second_button, third_button, fourth_button]) <= number_of_presses:
# Simulate the button presses on the bulbs
bulbs = [1] * min(number_of_bulbs, 6) # Only the first 6 bulbs matter
if first_button:
for i in range(len(bulbs)):
bulbs[i] = 1 - bulbs[i]
if second_button:
for i in range(0, len(bulbs), 2):
bulbs[i] = 1 - bulbs[i]
if third_button:
for i in range(1, len(bulbs), 2):
bulbs[i] = 1 - bulbs[i]
if fourth_button:
for i in range(0, len(bulbs), 3):
bulbs[i] = 1 - bulbs[i]
# Convert the state of the bulbs to a tuple and add to set
possible_states.add(tuple(bulbs))
# The number of unique states is the answer
return len(possible_states)| Case | How to Handle |
|---|---|
| n = 0, presses = 0 | Return 1 as there's only one state: all bulbs on. |
| n = 0, presses > 0 | Return 1 as there are no bulbs to change. |
| n > 0, presses = 0 | Return 1 as all bulbs are on initially. |
| n = 1, presses > 0 | Return 2 as only two states are possible: on or off. |
| n = 2, presses = 1 | Return 3, representing all on, first off, second off, and both off. |
| n = 3, presses = 1 | Return 4, representing all possible combinations. |
| presses is large (e.g., > 10) | Optimize by using presses % 2, as the effect of presses beyond a certain number repeats. |
| n is very large and presses is also large | The number of bulbs beyond 3 doesn't matter much because patterns repeat, so treat n as min(n, 3) to optimize computations. |