> ## Documentation Index
> Fetch the complete documentation index at: https://leetcode-py.wisl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> leetcode-py is a Python LeetCode practice environment generator with one CLI: lcpy. It is not a service or platform.
> Each problem is a directory under leetcode/ with README.md, solution.py, test_solution.py, helpers.py, and playground.ipynb. lcpy gen creates them from JSON templates bundled with the package.
> Examples are backed by tests; copy them verbatim.

# Bulb Switcher II Python Solution with Tests

> Tested Python solution for LeetCode 672 with 20 pytest cases. Generate a practice environment with lcpy.

LeetCode 672, [Medium](/catalog/medium). Topics: [Math](/catalog/topics/math), [Bit Manipulation](/catalog/topics/bit-manipulation), [Depth-First Search](/catalog/topics/depth-first-search), [Breadth-First Search](/catalog/topics/breadth-first-search). [View on LeetCode](https://leetcode.com/problems/bulb-switcher-ii/description/).

Generate this problem as a practice environment: tested reference solution, 20 [parametrized pytest cases](/practice/testing), and a playground notebook:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 672   # by problem number
lcpy gen -s bulb_switcher_ii   # by problem name
```

## Problem

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:

* **Button 1:** Flips the status of all the bulbs.
* **Button 2:** Flips the status of all the bulbs with even labels (i.e., `2, 4, ...`).
* **Button 3:** Flips the status of all the bulbs with odd labels (i.e., `1, 3, ...`).
* **Button 4:** Flips the status of all the bulbs with a label `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.

### Examples

```
Input: n = 1, presses = 1
Output: 2
Explanation: Status can be:
- [off] by pressing button 1
- [on] by pressing button 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
```

```
Input: n = 3, presses = 1
Output: 4
Explanation: Status can be:
- [off, off, off] by pressing button 1
- [on, off, on] by pressing button 2
- [off, on, off] by pressing button 3
- [off, on, on] by pressing button 4
```

### Constraints

* 1 \<= n \<= 1000
* 0 \<= presses \<= 1000

## Solution

Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bulb_switcher_ii/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/bulb_switcher_ii/test_solution.py):

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Solution:
    # Time: O(1) - at most 16 button-parity vectors, each scored on <= 3 bulbs
    # Space: O(1) - at most 8 distinct statuses
    def flip_lights(self, n: int, presses: int) -> int:
        # Bulb j flips iff: button 1 (always), button 2 (j even),
        # button 3 (j odd), button 4 (j % 3 == 1). Every bulb's fate is a fixed
        # XOR of these four parities, so for n >= 3 the first three bulbs
        # determine the whole room: two different parity vectors agreeing on
        # bulbs 1-3 also agree on b1^b3 and b4, hence differ on b1 and b3,
        # which every bulb sees. So counting distinct 3-bulb prefixes counts
        # distinct full configurations.
        bulbs = min(n, 3)
        statuses: set[tuple[bool, ...]] = set()
        for mask in range(16):
            used = mask.bit_count()
            if used > presses or (presses - used) % 2 != 0:
                continue
            statuses.add(
                tuple(
                    (
                        (mask & 1)
                        ^ ((mask >> 1) & 1 if bulb % 2 == 0 else 0)
                        ^ ((mask >> 2) & 1 if bulb % 2 == 1 else 0)
                        ^ ((mask >> 3) & 1 if bulb % 3 == 1 else 0)
                    )
                    == 0
                    for bulb in range(1, bulbs + 1)
                )
            )
        return len(statuses)
```

## Complexity

| Time | Space |
| - | - |
| O(1) - at most 16 button-parity vectors, each scored on \<= 3 bulbs | O(1) - at most 8 distinct statuses |

## Tags


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.