Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@
* [Test Int32 To Ipv4](https://github.com/BrianLusina/PythonSnips/blob/master/bit_manipulation/int32_to_ipv4/test_int32_to_ipv4.py)
* Minflips
* [Test Min Flips](https://github.com/BrianLusina/PythonSnips/blob/master/bit_manipulation/minflips/test_min_flips.py)
* Number Of 1 Bits
* [Test Number Of One Bits](https://github.com/BrianLusina/PythonSnips/blob/master/bit_manipulation/number_of_1_bits/test_number_of_one_bits.py)
* Single Number
* [Test Single Number](https://github.com/BrianLusina/PythonSnips/blob/master/bit_manipulation/single_number/test_single_number.py)

Expand Down
71 changes: 71 additions & 0 deletions bit_manipulation/number_of_1_bits/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Number of 1 Bits

Write a function that takes a 32-bit binary representation of an unsigned integer n and returns the count of its 1 bits.

The binary representation of an unsigned integer is a sequence of 0s and 1s that represents the integer's value using
base-2 notation. An example of the 32-bit binary representation of an unsigned integer 13 is 00000000000000000000000000001101.

## Constraint

- The input must be a 32-bit binary representation of an unsigned integer.

> Note: The input is passed to the function as an unsigned integer variable. In this lesson, we have displayed it as a
> string of binary numbers solely for visualization purposes.


## Solution

The first attempt to solve this would be to iterate over each bit in the 32-bit representation and keep increasing the
count, representing the number of 1 bits, every time we encounter the digit 1. This is the correct way to solve this
problem, and it even takes constant time and space complexity. However, this approach requires us to perform 32
iterations regardless of the number of 1 bits, which makes it a less efficient approach, specifically for integers with
a small number of 1 bits. For example, there are only three 1 bits in the unsigned integer 13, but we'll have to iterate
the entire 32 times to get to this number.
To avoid any unnecessary iterations, we can use bitwise manipulation to efficiently count the number of 1 bits in the
given unsigned integer. Here, we'll iterate through the bits of the binary representation that are actually 1s. This
means it only performs iterations equal to the number of 1 bits in the binary representation of the integer. For example,
if the given integer is 12 with the binary representation of 00000000000000000000000000001100, the loop will iterate only
twice, which is highly efficient.

First, we'll initialize a counter, count, to keep track of the number of 1 bits in the 32-bit binary representation of
an unsigned integer. Then, we'll start a loop that continues as long as the integer n is not zero, i.e., there is no 1 bit
left in the integer. This loop will iterate through each bit of the binary representation of n, starting from the least
significant bit. In each iteration:

> The least significant bit is the rightmost bit in the binary representation of a number.

- Check whether the least significant bit of n is equal to 1 using the bitwise AND operation.
- If the last bit is 1, increment the count by 1.
- Otherwise, continue with the loop.
- Once we are done checking the current bit, right-shift n by one position using the right bitwise shift operator. This
operation effectively shifts all bits one place to the right, discarding the last bit and making the next bit the new
least significant bit.

Eventually, count will have the total number of 1 bits, so we'll return it as the final result.

Let’s look at the following illustration to get a better understanding of the solution:

![Solution 1](./images/solutions/number_of_one_bits_solution_1.png)
![Solution 2](./images/solutions/number_of_one_bits_solution_2.png)
![Solution 3](./images/solutions/number_of_one_bits_solution_3.png)
![Solution 4](./images/solutions/number_of_one_bits_solution_4.png)
![Solution 5](./images/solutions/number_of_one_bits_solution_5.png)
![Solution 6](./images/solutions/number_of_one_bits_solution_6.png)
![Solution 7](./images/solutions/number_of_one_bits_solution_7.png)
![Solution 8](./images/solutions/number_of_one_bits_solution_8.png)
![Solution 9](./images/solutions/number_of_one_bits_solution_9.png)
![Solution 10](./images/solutions/number_of_one_bits_solution_10.png)
![Solution 11](./images/solutions/number_of_one_bits_solution_11.png)
![Solution 12](./images/solutions/number_of_one_bits_solution_12.png)
![Solution 13](./images/solutions/number_of_one_bits_solution_13.png)
![Solution 14](./images/solutions/number_of_one_bits_solution_14.png)
![Solution 15](./images/solutions/number_of_one_bits_solution_15.png)

### Time Complexity

In the worst case, the number of iterations in the loop can go up to 32, which is a fixed number. Therefore, the overall
time complexity for this solution is O(1).

### Space Complexity

The space complexity of this solution is O(1).
11 changes: 11 additions & 0 deletions bit_manipulation/number_of_1_bits/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
def count_bits(n: int) -> int:
count = 0

while n:
# Check the least significant bit by using AND
if n & 1:
count += 1
# Right-shift the number to move to the next bit
n >>= 1

return count
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions bit_manipulation/number_of_1_bits/test_number_of_one_bits.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import unittest
from parameterized import parameterized
from bit_manipulation.number_of_1_bits import count_bits

NUMBER_OF_ONE_BITS_TEST_CASES = [
("unsigned integer 3", 0b00000000000000000000000000000011, 2),
("unsigned integer 25", 0b00000000000000000000000000011001, 3),
("unsigned integer 725", 0b00000000000000000000001011010101, 6),
("unsigned integer 2500", 0b00000000000000000000100111000100, 5),
("unsigned integer 3253", 0b00000000000000000000110010110101, 7),
("unsigned integer 2147483647", 0b01111111111111111111111111111111, 31),
]


class NumberOfOneBitsTestCase(unittest.TestCase):
@parameterized.expand(NUMBER_OF_ONE_BITS_TEST_CASES)
def test_count_bits(self, _, n: int, expected: int):
actual = count_bits(n)
self.assertEqual(expected, actual)


if __name__ == '__main__':
unittest.main()
Loading