You are given n
bulbs, initially all off. You perform n
rounds of switches. In the first round, you turn on all the bulbs. In the second round, you turn off every second bulb. In the third round, you toggle every third bulb (turning on if it's off or turning off if it's on). You repeat this process for n
rounds. Your task is to write a function that, given the number of bulbs n
, returns the number of bulbs that are on after n
rounds.
Here's a breakdown of the process and some examples to illustrate the problem:
n
bulbs are off.i
: Toggle bulbs i
, 2i
, 3i
, 4i
, ...n
rounds.Here are some examples:
Example 1: n = 3
[off, off, off]
[on, on, on]
[on, off, on]
[on, off, off]
Example 2: n = 0
Example 3: n = 1
[off]
[on]
Example 4: n = 6
Can you provide an efficient algorithm to solve this problem? Explain your reasoning and the time complexity of your solution.
Let's explore the "Bulb Switcher" problem. The prompt states: There are n
bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it's off or turning off if it's on). For the ith
round, you toggle every ith
bulb. For the nth
round, you only toggle the last bulb. Return the number of bulbs that are on after n
rounds.
A straightforward approach is to simulate the entire process. We can use a boolean array to represent the state of each bulb. We iterate through each round, toggling the appropriate bulbs.
python def bulb_switcher_naive(n): bulbs = [False] * n # Initialize all bulbs to off (False)
for i in range(1, n + 1):
for j in range(i - 1, n, i):
bulbs[j] = not bulbs[j] # Toggle the bulb
return sum(bulbs) # Count the number of on bulbs (True)
Big(O) Run-time: O(n^2), due to the nested loops. Big(O) Space Usage: O(n), to store the boolean array representing the bulbs.
The key insight here is that a bulb's final state (on or off) depends on how many times it's toggled. A bulb is toggled once for each of its factors. For example, bulb number 12 is toggled by rounds 1, 2, 3, 4, 6, and 12.
If a number has an odd number of factors, the bulb will be on. If a number has an even number of factors, the bulb will be off.
Most numbers have an even number of factors because factors usually come in pairs. For example, the factors of 12 are (1, 12), (2, 6), and (3, 4).
However, perfect squares have an odd number of factors. For example, the factors of 9 are (1, 9) and (3, 3). The factor 3 is only counted once.
Therefore, the number of bulbs that are on is equal to the number of perfect squares less than or equal to n
.
python import math
def bulb_switcher_optimal(n): return int(math.sqrt(n))
Big(O) Run-time: O(1), as math.sqrt
takes constant time.
Big(O) Space Usage: O(1), as we are using a constant amount of extra space.
math.sqrt
function can handle large values of n without integer overflow problems (within the limits of floating-point precision).The optimal solution avoids simulating the entire process, resulting in significant time savings. By recognizing that only perfect squares will be on, we can directly calculate the result using the square root function.