From 933aa6e8a01e641ca2c38763b2dacd13b20802df Mon Sep 17 00:00:00 2001 From: Sweta Pal Date: Tue, 14 Oct 2025 10:18:27 +0530 Subject: [PATCH] feat(bit_manipulation): add swap_bits function with doctests and validation --- bit_manipulation/binary_swap_bits.py | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 bit_manipulation/binary_swap_bits.py diff --git a/bit_manipulation/binary_swap_bits.py b/bit_manipulation/binary_swap_bits.py new file mode 100644 index 000000000000..a69d7b3068cb --- /dev/null +++ b/bit_manipulation/binary_swap_bits.py @@ -0,0 +1,55 @@ +""" +Swaps two bits at given positions in an integer using bitwise operators. +Wikipedia explanation: https://en.wikipedia.org/wiki/Bit_manipulation +""" + + +def swap_bits(number: int, i: int, j: int) -> int: + """ + Swaps the bits at positions i and j (0-indexed from the right). + + >>> swap_bits(28, 0, 2) # 11100 → swap rightmost bits 0 and 2 + 25 + >>> swap_bits(15, 1, 2) # 1111 → swap bits 1 and 2 + 15 + >>> swap_bits(10, 0, 3) # 1010 → swap bits 0 and 3 + 3 + >>> swap_bits(10.5, 0, 3) + Traceback (most recent call last): + ... + TypeError: All arguments MUST be integers! + >>> swap_bits(-5, 1, 3) + Traceback (most recent call last): + ... + ValueError: The number MUST be non-negative! + >>> swap_bits(10, -1, 2) + Traceback (most recent call last): + ... + ValueError: Bit positions MUST be non-negative! + """ + + if not all(isinstance(x, int) for x in (number, i, j)): + raise TypeError("All arguments MUST be integers!") + + if number < 0: + raise ValueError("The number MUST be non-negative!") + + if i < 0 or j < 0: + raise ValueError("Bit positions MUST be non-negative!") + + # Extract the bits at positions i and j + bit_i = (number >> i) & 1 + bit_j = (number >> j) & 1 + + # Only swap if the bits are different + if bit_i != bit_j: + # XOR with a mask that has 1s at i and j + number ^= (1 << i) | (1 << j) + + return number + + +if _name_ == "_main_": + import doctest + + doctest.testmod() \ No newline at end of file