Heaps are tree-like data structures that allow storing elements in a specific - * way. Each node corresponds to an element and has one parent node (except for the root) and - * at most two children nodes. Every element contains a key, and those keys - * indicate how the tree shall be built. For instance, for a min-heap, the key of a node shall - * be greater than or equal to its parent's and lower than or equal to its children's (the opposite rule applies to a - * max-heap).
- *All heap-related operations (inserting or deleting an element, extracting the min or max) are performed in - * O(log n) time.
- * @author Nicolas Renard - * - * - */ -public interface Heap { - - /** - * - * @return the top element in the heap, the one with lowest key for min-heap or with - * the highest key for max-heap - * @throws Exception if heap is empty - */ - public abstract HeapElement getElement() throws EmptyHeapException; - /** - * Inserts an element in the heap. Adds it to then end and toggle it until it finds its - * right position. - * - * @param element an instance of the HeapElement class. - */ - public abstract void insertElement(HeapElement element); - - /** - * Delete an element in the heap. - * - * @param elementIndex int containing the position in the heap of the element to be deleted. - */ - public abstract void deleteElement(int elementIndex); - -} diff --git a/Data Structures/Heaps/HeapElement.java b/Data Structures/Heaps/HeapElement.java deleted file mode 100644 index e0cc93ccbfe0..000000000000 --- a/Data Structures/Heaps/HeapElement.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * - */ -package heaps; - -import java.lang.Double; -import java.lang.Object; - -/** - * Class for heap elements.A heap element contains two attributes: a key which will be used to build the tree (int - * or double, either primitive type or object) and any kind of IMMUTABLE object the user sees fit - * to carry any information he/she likes. Be aware that the use of a mutable object might - * jeopardize the integrity of this information.
- * @author Nicolas Renard - * - */ -public class HeapElement { - private final double key; - private final Object additionalInfo; - - // Constructors - - /** - * - * @param key : a number of primitive type 'double' - * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry - * additional information of use for the user - */ - public HeapElement(double key, Object info) { - this.key = key; - this.additionalInfo = info; - } - - /** - * - * @param key : a number of primitive type 'int' - * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry - * additional information of use for the user - */ - public HeapElement(int key, Object info) { - this.key = key; - this.additionalInfo = info; - } - - /** - * - * @param key : a number of object type 'Integer' - * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry - * additional information of use for the user - */ - public HeapElement(Integer key, Object info) { - this.key = key; - this.additionalInfo = info; - } - - /** - * - * @param key : a number of object type 'Double' - * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry - * additional information of use for the user - */ - public HeapElement(Double key, Object info) { - this.key = key; - this.additionalInfo = info; - } - - /** - * - * @param key : a number of primitive type 'double' - */ - public HeapElement(double key) { - this.key = key; - this.additionalInfo = null; - } - - /** - * - * @param key : a number of primitive type 'int' - */ - public HeapElement(int key) { - this.key = key; - this.additionalInfo = null; - } - - /** - * - * @param key : a number of object type 'Integer' - */ - public HeapElement(Integer key) { - this.key = key; - this.additionalInfo = null; - } - - /** - * - * @param key : a number of object type 'Double' - */ - public HeapElement(Double key) { - this.key = key; - this.additionalInfo = null; - } - - // Getters - /** - * @return the object containing the additional info provided by the user. - */ - public Object getInfo() { - return additionalInfo; - } - /** - * @return the key value of the element - */ - public double getKey() { - return key; - } - - // Overridden object methods - - public String toString() { - return "Key: " + key + " - " +additionalInfo.toString(); - } - /** - * - * @param otherHeapElement - * @return true if the keys on both elements are identical and the additional info objects - * are identical. - */ - public boolean equals(HeapElement otherHeapElement) { - return (this.key == otherHeapElement.key) && (this.additionalInfo.equals(otherHeapElement.additionalInfo)); - } -} diff --git a/Data Structures/Heaps/MaxHeap.java b/Data Structures/Heaps/MaxHeap.java deleted file mode 100644 index 5f774e3534a8..000000000000 --- a/Data Structures/Heaps/MaxHeap.java +++ /dev/null @@ -1,115 +0,0 @@ -package heaps; - -import java.util.ArrayList; -import java.util.List; - -/** - * Heap tree where a node's key is higher than or equal to its parent's and lower than or equal - * to its children's. - * @author Nicolas Renard - * - */ -public class MaxHeap implements Heap { - - private final List+ * This filter applies an exponential moving average to a sequence of audio + * signal values, making it useful for smoothing out rapid fluctuations. + * The smoothing factor (alpha) controls the degree of smoothing. + * + *
+ * Based on the definition from + * Wikipedia link. + */ +public class EMAFilter { + private final double alpha; + private double emaValue; + + /** + * Constructs an EMA filter with a given smoothing factor. + * + * @param alpha Smoothing factor (0 < alpha <= 1) + * @throws IllegalArgumentException if alpha is not in (0, 1] + */ + public EMAFilter(double alpha) { + if (alpha <= 0 || alpha > 1) { + throw new IllegalArgumentException("Alpha must be between 0 and 1."); + } + this.alpha = alpha; + this.emaValue = 0.0; + } + + /** + * Applies the EMA filter to an audio signal array. + * EMA formula: + * EMA = alpha * currentSample + (1 - alpha) * previousEMA + * + * @param audioSignal Array of audio samples to process + * @return Array of processed (smoothed) samples + */ + public double[] apply(double[] audioSignal) { + if (audioSignal == null || audioSignal.length == 0) { + return new double[0]; + } + double[] emaSignal = new double[audioSignal.length]; + emaValue = audioSignal[0]; + emaSignal[0] = emaValue; + for (int i = 1; i < audioSignal.length; i++) { + emaValue = alpha * audioSignal[i] + (1 - alpha) * emaValue; + emaSignal[i] = emaValue; + } + return emaSignal; + } +} diff --git a/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java b/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java new file mode 100644 index 000000000000..fbc095909541 --- /dev/null +++ b/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java @@ -0,0 +1,93 @@ +package com.thealgorithms.audiofilters; + +/** + * N-Order IIR Filter Assumes inputs are normalized to [-1, 1] + * + * Based on the difference equation from + * Wikipedia link + */ +public class IIRFilter { + + private final int order; + private final double[] coeffsA; + private final double[] coeffsB; + private final double[] historyX; + private final double[] historyY; + + /** + * Construct an IIR Filter + * + * @param order the filter's order + * @throws IllegalArgumentException if order is zero or less + */ + public IIRFilter(int order) throws IllegalArgumentException { + if (order < 1) { + throw new IllegalArgumentException("order must be greater than zero"); + } + + this.order = order; + coeffsA = new double[order + 1]; + coeffsB = new double[order + 1]; + + // Sane defaults + coeffsA[0] = 1.0; + coeffsB[0] = 1.0; + + historyX = new double[order]; + historyY = new double[order]; + } + + /** + * Set coefficients + * + * @param aCoeffs Denominator coefficients + * @param bCoeffs Numerator coefficients + * @throws IllegalArgumentException if {@code aCoeffs} or {@code bCoeffs} is + * not of size {@code order}, or if {@code aCoeffs[0]} is 0.0 + */ + public void setCoeffs(double[] aCoeffs, double[] bCoeffs) throws IllegalArgumentException { + if (aCoeffs.length != order) { + throw new IllegalArgumentException("aCoeffs must be of size " + order + ", got " + aCoeffs.length); + } + + if (aCoeffs[0] == 0.0) { + throw new IllegalArgumentException("aCoeffs.get(0) must not be zero"); + } + + if (bCoeffs.length != order) { + throw new IllegalArgumentException("bCoeffs must be of size " + order + ", got " + bCoeffs.length); + } + + for (int i = 0; i < order; i++) { + coeffsA[i] = aCoeffs[i]; + coeffsB[i] = bCoeffs[i]; + } + } + + /** + * Process a single sample + * + * @param sample the sample to process + * @return the processed sample + */ + public double process(double sample) { + double result = 0.0; + + // Process + for (int i = 1; i <= order; i++) { + result += (coeffsB[i] * historyX[i - 1] - coeffsA[i] * historyY[i - 1]); + } + result = (result + coeffsB[0] * sample) / coeffsA[0]; + + // Feedback + for (int i = order - 1; i > 0; i--) { + historyX[i] = historyX[i - 1]; + historyY[i] = historyY[i - 1]; + } + + historyX[0] = sample; + historyY[0] = result; + + return result; + } +} diff --git a/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java new file mode 100644 index 000000000000..269880b8ddae --- /dev/null +++ b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java @@ -0,0 +1,126 @@ +package com.thealgorithms.backtracking; + +import java.util.ArrayList; +import java.util.List; + +/** + * Finds all possible simple paths from a given source vertex to a destination vertex + * in a directed graph using backtracking. + * + *
This algorithm performs a Depth First Search (DFS) traversal while keeping track + * of visited vertices to avoid cycles. Whenever the destination vertex is reached, + * the current path is stored as one valid path.
+ * + *Key Characteristics:
+ *Time Complexity:
+ *Space Complexity:
+ *This implementation is intended for educational purposes.
+ * + * @see Depth First Search + */ + +@SuppressWarnings({"rawtypes", "unchecked"}) +public class AllPathsFromSourceToTarget { + + // No. of vertices in graph + private final int v; + + // To store the paths from source to destination + static ListGiven an {@code n x n} binary maze where {@code 1} represents an open cell + * and {@code 0} represents a blocked cell, find all paths for a rat starting at + * the top-left cell {@code (0, 0)} to reach the bottom-right cell {@code (n-1, n-1)}. + * + *
The rat can move in four directions: Up (U), Down (D), Left (L), Right (R). + * Each cell may be visited at most once per path. + * + *
Time Complexity: O(4^(n²)) in the worst case (four choices per cell). + * Space Complexity: O(n²) for the visited matrix and recursion stack. + * + *
Example: + *
+ * maze = { {1, 0, 0, 0},
+ * {1, 1, 0, 1},
+ * {0, 1, 0, 0},
+ * {0, 1, 1, 1} }
+ * Output: ["DDRDRR", "DRDDRR"] (two valid paths)
+ *
+ *
+ * @see Maze solving algorithm
+ * @author the-Sunny-Sharma (GitHub)
+ */
+public final class RatInAMaze {
+
+ private RatInAMaze() {
+ }
+
+ /**
+ * Finds all paths from the top-left to the bottom-right of the given maze.
+ *
+ * @param maze an {@code n x n} binary matrix where {@code 1} = open, {@code 0} = blocked
+ * @return a sorted list of all valid path strings using directions D, L, R, U;
+ * an empty list if no path exists
+ * @throws IllegalArgumentException if the maze is null, empty, or not square
+ */
+ public static List
+ * int decimal = BcdConversion.bcdToDecimal(0x1234);
+ * System.out.println("BCD 0x1234 to decimal: " + decimal); // Output: 1234
+ *
+ * int bcd = BcdConversion.decimalToBcd(1234);
+ * System.out.println("Decimal 1234 to BCD: " + Integer.toHexString(bcd)); // Output: 0x1234
+ *
+ */
+public final class BcdConversion {
+ private BcdConversion() {
+ }
+
+ /**
+ * Converts a BCD (Binary-Coded Decimal) number to a decimal number.
+ * Steps: + *
1. Validate the BCD number to ensure all digits are between 0 and 9. + *
2. Extract the last 4 bits (one BCD digit) from the BCD number. + *
3. Multiply the extracted digit by the corresponding power of 10 and add it to the decimal number. + *
4. Shift the BCD number right by 4 bits to process the next BCD digit. + *
5. Repeat steps 1-4 until the BCD number is zero. + * + * @param bcd The BCD number. + * @return The corresponding decimal number. + * @throws IllegalArgumentException if the BCD number contains invalid digits. + */ + public static int bcdToDecimal(int bcd) { + int decimal = 0; + int multiplier = 1; + + // Validate BCD digits + while (bcd > 0) { + int digit = bcd & 0xF; + if (digit > 9) { + throw new IllegalArgumentException("Invalid BCD digit: " + digit); + } + decimal += digit * multiplier; + multiplier *= 10; + bcd >>= 4; + } + return decimal; + } + + /** + * Converts a decimal number to BCD (Binary-Coded Decimal). + *
Steps: + *
1. Check if the decimal number is within the valid range for BCD (0 to 9999). + *
2. Extract the last decimal digit from the decimal number. + *
3. Shift the digit to the correct BCD position and add it to the BCD number. + *
4. Remove the last decimal digit from the decimal number. + *
5. Repeat steps 2-4 until the decimal number is zero. + * + * @param decimal The decimal number. + * @return The corresponding BCD number. + * @throws IllegalArgumentException if the decimal number is greater than 9999. + */ + public static int decimalToBcd(int decimal) { + if (decimal < 0 || decimal > 9999) { + throw new IllegalArgumentException("Value out of bounds for BCD representation: " + decimal); + } + + int bcd = 0; + int shift = 0; + while (decimal > 0) { + int digit = decimal % 10; + bcd |= (digit << (shift * 4)); + decimal /= 10; + shift++; + } + return bcd; + } +} diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java b/src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java new file mode 100644 index 000000000000..0d6fd140c720 --- /dev/null +++ b/src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java @@ -0,0 +1,43 @@ +package com.thealgorithms.bitmanipulation; + +/** + * This class contains a method to check if the binary representation of a number is a palindrome. + *
+ * A binary palindrome is a number whose binary representation is the same when read from left to right and right to left. + * For example, the number 9 has a binary representation of 1001, which is a palindrome. + * The number 10 has a binary representation of 1010, which is not a palindrome. + *
+ * + * @author Hardvan + */ +public final class BinaryPalindromeCheck { + private BinaryPalindromeCheck() { + } + + /** + * Checks if the binary representation of a number is a palindrome. + * + * @param x The number to check. + * @return True if the binary representation is a palindrome, otherwise false. + */ + public static boolean isBinaryPalindrome(int x) { + int reversed = reverseBits(x); + return x == reversed; + } + + /** + * Helper function to reverse all the bits of an integer. + * + * @param x The number to reverse the bits of. + * @return The number with reversed bits. + */ + private static int reverseBits(int x) { + int result = 0; + while (x > 0) { + result <<= 1; + result |= (x & 1); + x >>= 1; + } + return result; + } +} diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BitRotate.java b/src/main/java/com/thealgorithms/bitmanipulation/BitRotate.java new file mode 100644 index 000000000000..226e09e78d1f --- /dev/null +++ b/src/main/java/com/thealgorithms/bitmanipulation/BitRotate.java @@ -0,0 +1,83 @@ +package com.thealgorithms.bitmanipulation; + +/** + * Utility class for performing circular bit rotations on 32-bit integers. + * Bit rotation is a circular shift operation where bits shifted out on one end + * are reinserted on the opposite end. + * + *This class provides methods for both left and right circular rotations, + * supporting only 32-bit integer operations with proper shift normalization + * and error handling.
+ * + * @see Bit Rotation + */ +public final class BitRotate { + + /** + * Private constructor to prevent instantiation. + * This is a utility class with only static methods. + */ + private BitRotate() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } + + /** + * Performs a circular left rotation (left shift) on a 32-bit integer. + * Bits shifted out from the left side are inserted on the right side. + * + * @param value the 32-bit integer value to rotate + * @param shift the number of positions to rotate left (must be non-negative) + * @return the result of left rotating the value by the specified shift amount + * @throws IllegalArgumentException if shift is negative + * + * @example + * // Binary: 10000000 00000000 00000000 00000001 + * rotateLeft(0x80000001, 1) + * // Returns: 3 (binary: 00000000 00000000 00000000 00000011) + */ + public static int rotateLeft(int value, int shift) { + if (shift < 0) { + throw new IllegalArgumentException("Shift amount cannot be negative: " + shift); + } + + // Normalize shift to the range [0, 31] using modulo 32 + shift = shift % 32; + + if (shift == 0) { + return value; + } + + // Left rotation: (value << shift) | (value >>> (32 - shift)) + return (value << shift) | (value >>> (32 - shift)); + } + + /** + * Performs a circular right rotation (right shift) on a 32-bit integer. + * Bits shifted out from the right side are inserted on the left side. + * + * @param value the 32-bit integer value to rotate + * @param shift the number of positions to rotate right (must be non-negative) + * @return the result of right rotating the value by the specified shift amount + * @throws IllegalArgumentException if shift is negative + * + * @example + * // Binary: 00000000 00000000 00000000 00000011 + * rotateRight(3, 1) + * // Returns: -2147483647 (binary: 10000000 00000000 00000000 00000001) + */ + public static int rotateRight(int value, int shift) { + if (shift < 0) { + throw new IllegalArgumentException("Shift amount cannot be negative: " + shift); + } + + // Normalize shift to the range [0, 31] using modulo 32 + shift = shift % 32; + + if (shift == 0) { + return value; + } + + // Right rotation: (value >>> shift) | (value << (32 - shift)) + return (value >>> shift) | (value << (32 - shift)); + } +} diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java b/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java new file mode 100644 index 000000000000..634c9e7b3b44 --- /dev/null +++ b/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java @@ -0,0 +1,33 @@ +package com.thealgorithms.bitmanipulation; + +/** + * Utility class for performing bit-swapping operations on integers. + * This class cannot be instantiated. + */ +public final class BitSwap { + private BitSwap() { + } + + /** + * Swaps two bits at specified positions in an integer. + * + * @param data The input integer whose bits need to be swapped + * @param posA The position of the first bit (0-based, from least significant) + * @param posB The position of the second bit (0-based, from least significant) + * @return The modified value with swapped bits + * @throws IllegalArgumentException if either position is negative or ≥ 32 + */ + + public static int bitSwap(int data, final int posA, final int posB) { + if (posA < 0 || posA >= Integer.SIZE || posB < 0 || posB >= Integer.SIZE) { + throw new IllegalArgumentException("Bit positions must be between 0 and 31"); + } + + boolean bitA = ((data >> posA) & 1) != 0; + boolean bitB = ((data >> posB) & 1) != 0; + if (bitA != bitB) { + data ^= (1 << posA) ^ (1 << posB); + } + return data; + } +} diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BitwiseGCD.java b/src/main/java/com/thealgorithms/bitmanipulation/BitwiseGCD.java new file mode 100644 index 000000000000..516563459256 --- /dev/null +++ b/src/main/java/com/thealgorithms/bitmanipulation/BitwiseGCD.java @@ -0,0 +1,147 @@ +package com.thealgorithms.bitmanipulation; + +import java.math.BigInteger; + +/** + * Bitwise GCD implementation with full-range support utilities. + * + *This class provides a fast binary (Stein's) GCD implementation for {@code long} + * inputs and a BigInteger-backed API for full 2's-complement range support (including + * {@code Long.MIN_VALUE}). The {@code long} implementation is efficient and avoids + * division/modulo operations. For edge-cases that overflow signed-64-bit ranges + * (e.g., gcd(Long.MIN_VALUE, 0) = 2^63), use the BigInteger API {@code gcdBig}. + * + *
Behaviour: + *
Handles negative inputs. If either input is {@code Long.MIN_VALUE} the
+ * method delegates to the BigInteger implementation and will throw {@link ArithmeticException}
+ * if the result cannot be represented as a signed {@code long}.
+ *
+ * @param a first value (may be negative)
+ * @param b second value (may be negative)
+ * @return non-negative gcd as a {@code long}
+ * @throws ArithmeticException when the exact gcd does not fit into a signed {@code long}
+ */
+ public static long gcd(long a, long b) {
+ // Trivial cases
+ if (a == 0L) {
+ return absOrThrowIfOverflow(b);
+ }
+ if (b == 0L) {
+ return absOrThrowIfOverflow(a);
+ }
+
+ // If either is Long.MIN_VALUE, absolute value doesn't fit into signed long.
+ if (a == Long.MIN_VALUE || b == Long.MIN_VALUE) {
+ // Delegate to BigInteger and try to return a long if it fits
+ BigInteger g = gcdBig(BigInteger.valueOf(a), BigInteger.valueOf(b));
+ return g.longValueExact();
+ }
+
+ // Work with non-negative long values now (safe because we excluded Long.MIN_VALUE)
+ a = (a < 0) ? -a : a;
+ b = (b < 0) ? -b : b;
+
+ // Count common factors of 2
+ int commonTwos = Long.numberOfTrailingZeros(a | b);
+
+ // Remove all factors of 2 from a
+ a >>= Long.numberOfTrailingZeros(a);
+
+ while (b != 0L) {
+ // Remove all factors of 2 from b
+ b >>= Long.numberOfTrailingZeros(b);
+
+ // Now both a and b are odd. Ensure a <= b
+ if (a > b) {
+ long tmp = a;
+ a = b;
+ b = tmp;
+ }
+
+ // b >= a; subtract a from b (result is even)
+ b = b - a;
+ }
+
+ // Restore common powers of two
+ return a << commonTwos;
+ }
+
+ /**
+ * Helper to return absolute value of x unless x == Long.MIN_VALUE, in which
+ * case we delegate to BigInteger and throw to indicate overflow.
+ */
+ private static long absOrThrowIfOverflow(long x) {
+ if (x == Long.MIN_VALUE) {
+ // |Long.MIN_VALUE| = 2^63 which does not fit into signed long
+ throw new ArithmeticException("Absolute value of Long.MIN_VALUE does not fit into signed long. Use gcdBig() for full-range support.");
+ }
+ return (x < 0) ? -x : x;
+ }
+
+ /**
+ * Computes GCD for an array of {@code long} values. Returns 0 for empty/null arrays.
+ * If any intermediate gcd cannot be represented in signed long (rare), an ArithmeticException
+ * will be thrown.
+ */
+ public static long gcd(long... values) {
+
+ if (values == null || values.length == 0) {
+ return 0L;
+ }
+ long result = values[0];
+ for (int i = 1; i < values.length; i++) {
+ result = gcd(result, values[i]);
+ if (result == 1L) {
+ return 1L; // early exit
+ }
+ }
+ return result;
+ }
+
+ /**
+ * BigInteger-backed gcd that works for the full integer range (and beyond).
+ * This is the recommended method when inputs may be Long.MIN_VALUE or when you
+ * need an exact result even if it is greater than Long.MAX_VALUE.
+ * @param a first value (may be negative)
+ * @param b second value (may be negative)
+ * @return non-negative gcd as a {@link BigInteger}
+ */
+ public static BigInteger gcdBig(BigInteger a, BigInteger b) {
+
+ if (a == null || b == null) {
+ throw new NullPointerException("Arguments must not be null");
+ }
+ return a.abs().gcd(b.abs());
+ }
+
+ /**
+ * Convenience overload that accepts signed-64 inputs and returns BigInteger gcd.
+ */
+ public static BigInteger gcdBig(long a, long b) {
+ return gcdBig(BigInteger.valueOf(a), BigInteger.valueOf(b));
+ }
+
+ /**
+ * int overload for convenience.
+ */
+ public static int gcd(int a, int b) {
+ return (int) gcd((long) a, (long) b);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java b/src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java
new file mode 100644
index 000000000000..869466320831
--- /dev/null
+++ b/src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java
@@ -0,0 +1,111 @@
+package com.thealgorithms.bitmanipulation;
+
+import java.util.List;
+
+/**
+ * Implements various Boolean algebra gates (AND, OR, NOT, XOR, NAND, NOR)
+ */
+public final class BooleanAlgebraGates {
+
+ private BooleanAlgebraGates() {
+ // Prevent instantiation
+ }
+
+ /**
+ * Represents a Boolean gate that takes multiple inputs and returns a result.
+ */
+ interface BooleanGate {
+ /**
+ * Evaluates the gate with the given inputs.
+ *
+ * @param inputs The input values for the gate.
+ * @return The result of the evaluation.
+ */
+ boolean evaluate(List This class provides a method to extract the value of the Nth bit (either 0 or 1)
+ * from the binary representation of a given integer.
+ *
+ * Example:
+ * Author: Tuhinm2002
+ */
+public final class FindNthBit {
+
+ /**
+ * Private constructor to prevent instantiation.
+ *
+ * This is a utility class, and it should not be instantiated.
+ * Attempting to instantiate this class will throw an UnsupportedOperationException.
+ */
+ private FindNthBit() {
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+ /**
+ * Finds the value of the Nth bit of the given number.
+ *
+ * This method uses bitwise operations to extract the Nth bit from the
+ * binary representation of the given integer.
+ *
+ * @param num the integer number whose Nth bit is to be found
+ * @param n the bit position (1-based) to retrieve
+ * @return the value of the Nth bit (0 or 1)
+ * @throws IllegalArgumentException if the bit position is less than 1
+ */
+ public static int findNthBit(int num, int n) {
+ if (n < 1) {
+ throw new IllegalArgumentException("Bit position must be greater than or equal to 1.");
+ }
+ // Shifting the number to the right by (n - 1) positions and checking the last bit
+ return (num & (1 << (n - 1))) >> (n - 1);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java b/src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java
new file mode 100644
index 000000000000..9a761c572e2c
--- /dev/null
+++ b/src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java
@@ -0,0 +1,33 @@
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * This class provides a method to find the first differing bit
+ * between two integers.
+ *
+ * Example:
+ * x = 10 (1010 in binary)
+ * y = 12 (1100 in binary)
+ * The first differing bit is at index 1 (0-based)
+ * So, the output will be 1
+ *
+ * @author Hardvan
+ */
+public final class FirstDifferentBit {
+ private FirstDifferentBit() {
+ }
+
+ /**
+ * Identifies the index of the first differing bit between two integers.
+ * Steps:
+ * 1. XOR the two integers to get the differing bits
+ * 2. Find the index of the first set bit in XOR result
+ *
+ * @param x the first integer
+ * @param y the second integer
+ * @return the index of the first differing bit (0-based)
+ */
+ public static int firstDifferentBit(int x, int y) {
+ int diff = x ^ y;
+ return Integer.numberOfTrailingZeros(diff);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/GenerateSubsets.java b/src/main/java/com/thealgorithms/bitmanipulation/GenerateSubsets.java
new file mode 100644
index 000000000000..f1b812495c1b
--- /dev/null
+++ b/src/main/java/com/thealgorithms/bitmanipulation/GenerateSubsets.java
@@ -0,0 +1,44 @@
+package com.thealgorithms.bitmanipulation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides a method to generate all subsets (power set)
+ * of a given set using bit manipulation.
+ *
+ * @author Hardvan
+ */
+public final class GenerateSubsets {
+ private GenerateSubsets() {
+ }
+
+ /**
+ * Generates all subsets of a given set using bit manipulation.
+ * Steps:
+ * 1. Iterate over all numbers from 0 to 2^n - 1.
+ * 2. For each number, iterate over all bits from 0 to n - 1.
+ * 3. If the i-th bit of the number is set, add the i-th element of the set to the current subset.
+ * 4. Add the current subset to the list of subsets.
+ * 5. Return the list of subsets.
+ *
+ * @param set the input set of integers
+ * @return a list of all subsets represented as lists of integers
+ */
+ public static List
+ * nextHigherPowerOfTwo method finds the next higher power of two.
+ * nextLowerPowerOfTwo method finds the next lower power of two.
+ * Both methods take an integer as input and return the next higher or lower power of two.
+ * If the input is less than 1, the next higher power of two is 1.
+ * If the input is less than or equal to 1, the next lower power of two is 0.
+ * nextHigherPowerOfTwo method uses bitwise operations to find the next higher power of two.
+ * nextLowerPowerOfTwo method uses Integer.highestOneBit method to find the next lower power of two.
+ * The time complexity of both methods is O(1).
+ * The space complexity of both methods is O(1).
+ * {@code
+ * int result = FindNthBit.findNthBit(5, 2); // returns 0 as the 2nd bit of 5 (binary 101) is 0.
+ * }
+ *
+ * > generateSubsets(int[] set) {
+ int n = set.length;
+ List
> subsets = new ArrayList<>();
+
+ for (int mask = 0; mask < (1 << n); mask++) {
+ List