From f99f0d6e21248cd0f51027dd98e9515b01bf7e93 Mon Sep 17 00:00:00 2001 From: DataWorshipper Date: Thu, 2 Oct 2025 01:26:38 +0530 Subject: [PATCH 1/4] Add sliding window XOR implementation with tests in C++ --- bit_manipulation/sliding_window_xor.cpp | 130 ++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 bit_manipulation/sliding_window_xor.cpp diff --git a/bit_manipulation/sliding_window_xor.cpp b/bit_manipulation/sliding_window_xor.cpp new file mode 100644 index 0000000000..829cec4a6e --- /dev/null +++ b/bit_manipulation/sliding_window_xor.cpp @@ -0,0 +1,130 @@ +/** + * @file + * @brief Implementation to [calculate XOR of sliding window of size k in an array of n integers] + * (https://cses.fi/problemset/task/3426) + * + * @details + * We are given an array of n integers. Our task is to calculate the bitwise XOR of each + * window of k elements, from left to right, and cumulatively XOR the results into a single value. + * + * Worst Case Time Complexity: O(n) + * Space Complexity: O(n) + * + * @author [Abhiraj Mandal](https://github.com/DataWorshipper) + */ + +#include /// for assert +#include +#include +#include /// for IO operations + +/** + * @namespace bit_manipulation + * @brief Bit manipulation algorithms + */ +namespace bit_manipulation { +/** + * @namespace sliding_window_xor + * @brief Functions for cumulative XOR of sliding windows in arrays + */ +namespace sliding_window_xor { + +/** + * @brief Computes cumulative XOR of all windows of size k + * + * @param n Size of the array + * @param k Window size + * @param x Initial value to generate the array + * @param a Multiplier in array generation + * @param b Increment in array generation + * @param c Modulo in array generation + * @returns std::uint64_t The cumulative XOR of all windows of size k + * + * @details + * This function generates the array using the recurrence: + * arr[0] = x + * arr[i] = (a * arr[i-1] + b) % c + * + * It maintains a sliding window of size k using two pointers l and r: + * - x1 stores the XOR of the current window + * - x2 stores the cumulative XOR of all valid windows + * + * This approach ensures that the algorithm runs in O(n) time. + */ +std::uint64_t compute( + std::uint64_t n, + std::uint64_t k, + std::uint64_t x, + std::uint64_t a, + std::uint64_t b, + std::uint64_t c) { + + // Generate the array of n elements + std::vector arr(n); + arr[0] = x; // First element of the array + + for (std::uint64_t i = 1; i < n; ++i) { + arr[i] = (a * arr[i - 1] + b) % c; // recurrence relation + } + + std::uint64_t x1 = 0; // XOR of the current window + std::uint64_t x2 = 0; // Cumulative XOR of all windows of size k + std::uint64_t l = 0; // Left pointer of sliding window + std::uint64_t r = 0; // Right pointer of sliding window + + // Slide the window over the array + while (r < n) { + x1 ^= arr[r]; // include current element in window XOR + + // Shrink window from left if size exceeds k + while (r - l + 1 > k) { + x1 ^= arr[l]; // remove leftmost element from window XOR + ++l; + } + + // If window size equals k, add it to cumulative XOR + if (r - l + 1 == k) { + x2 ^= x1; + } + + ++r; // Move right pointer + } + + return x2; // Return cumulative XOR of all windows +} + +} // namespace sliding_window_xor +} // namespace bit_manipulation + +/** + * @brief Self-test implementation + */ +static void test() { + using bit_manipulation::sliding_window_xor::compute; + + // Testcase 1: n = 100, k = 20, expected = 1019 + assert(compute(100, 20, 3, 7, 1, 997) == 1019); + + // Testcase 2: n = 2, k = 1, expected = 2 + assert(compute(2, 1, 2, 3, 4, 5) == 2); + + // Testcase 3: n = 5, k = 2 + assert(compute(5, 2, 1, 1, 1, 100) == 0 ^ 3 ^ 1 ^ 7); + + // Testcase 4: n = 3, k = 5, expected = 0 + assert(compute(3, 5, 5, 2, 1, 100) == 0); + + // Testcase 5: n = 4, k = 4, expected = 0 + assert(compute(4, 4, 3, 1, 0, 10) == 0); + + std::cout << "All test cases successfully passed!" << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // run self-test implementations + return 0; +} \ No newline at end of file From 81e995f72a1f854479a241c9edd55431c24fb364 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 1 Oct 2025 19:57:40 +0000 Subject: [PATCH 2/4] clang-format and clang-tidy fixes for f99f0d6e --- bit_manipulation/sliding_window_xor.cpp | 39 +++++++++++-------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/bit_manipulation/sliding_window_xor.cpp b/bit_manipulation/sliding_window_xor.cpp index 829cec4a6e..2843de51b8 100644 --- a/bit_manipulation/sliding_window_xor.cpp +++ b/bit_manipulation/sliding_window_xor.cpp @@ -1,22 +1,23 @@ /** * @file - * @brief Implementation to [calculate XOR of sliding window of size k in an array of n integers] - * (https://cses.fi/problemset/task/3426) + * @brief Implementation to [calculate XOR of sliding window of size k in an + * array of n integers] (https://cses.fi/problemset/task/3426) * * @details - * We are given an array of n integers. Our task is to calculate the bitwise XOR of each - * window of k elements, from left to right, and cumulatively XOR the results into a single value. - * + * We are given an array of n integers. Our task is to calculate the bitwise XOR + * of each window of k elements, from left to right, and cumulatively XOR the + * results into a single value. + * * Worst Case Time Complexity: O(n) * Space Complexity: O(n) - * + * * @author [Abhiraj Mandal](https://github.com/DataWorshipper) */ -#include /// for assert -#include -#include +#include /// for assert +#include #include /// for IO operations +#include /** * @namespace bit_manipulation @@ -31,7 +32,7 @@ namespace sliding_window_xor { /** * @brief Computes cumulative XOR of all windows of size k - * + * * @param n Size of the array * @param k Window size * @param x Initial value to generate the array @@ -39,26 +40,20 @@ namespace sliding_window_xor { * @param b Increment in array generation * @param c Modulo in array generation * @returns std::uint64_t The cumulative XOR of all windows of size k - * + * * @details * This function generates the array using the recurrence: * arr[0] = x * arr[i] = (a * arr[i-1] + b) % c - * + * * It maintains a sliding window of size k using two pointers l and r: * - x1 stores the XOR of the current window * - x2 stores the cumulative XOR of all valid windows - * + * * This approach ensures that the algorithm runs in O(n) time. */ -std::uint64_t compute( - std::uint64_t n, - std::uint64_t k, - std::uint64_t x, - std::uint64_t a, - std::uint64_t b, - std::uint64_t c) { - +std::uint64_t compute(std::uint64_t n, std::uint64_t k, std::uint64_t x, + std::uint64_t a, std::uint64_t b, std::uint64_t c) { // Generate the array of n elements std::vector arr(n); arr[0] = x; // First element of the array @@ -109,7 +104,7 @@ static void test() { assert(compute(2, 1, 2, 3, 4, 5) == 2); // Testcase 3: n = 5, k = 2 - assert(compute(5, 2, 1, 1, 1, 100) == 0 ^ 3 ^ 1 ^ 7); + assert(compute(5, 2, 1, 1, 1, 100) == 0 ^ 3 ^ 1 ^ 7); // Testcase 4: n = 3, k = 5, expected = 0 assert(compute(3, 5, 5, 2, 1, 100) == 0); From 99aef441e5f1ed7a1c54cf94d4a14f67e9cd5092 Mon Sep 17 00:00:00 2001 From: Abhiraj Mandal <152878306+DataWorshipper@users.noreply.github.com> Date: Thu, 2 Oct 2025 10:26:18 +0530 Subject: [PATCH 3/4] git commit -m "Add Bitwise Trie solution for Maximum XOR problem" --- bit_manipulation/max_xor_bit_trie.cpp | 209 ++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 bit_manipulation/max_xor_bit_trie.cpp diff --git a/bit_manipulation/max_xor_bit_trie.cpp b/bit_manipulation/max_xor_bit_trie.cpp new file mode 100644 index 0000000000..9f1413cdbb --- /dev/null +++ b/bit_manipulation/max_xor_bit_trie.cpp @@ -0,0 +1,209 @@ +/** + * @file + * @brief Bitwise Trie implementation to compute the maximum XOR of two numbers in an array + * (https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/) + * + * @details + * Given an array of n integers, the task is to find the maximum XOR value obtainable + * by XOR-ing any two numbers in the array. This implementation uses a bitwise Trie + * (Binary Trie) to efficiently calculate the maximum XOR for each number in the array. + * + * Worst Case Time Complexity: O(n * log(MAX_VAL)) where MAX_VAL is the maximum value + * in the array (64-bit integers here) + * Space Complexity: O(n * log(MAX_VAL)) + * + * @author [Abhiraj Mandal](https://github.com/DataWorshipper) + */ + + +#include // for std::max +#include // for assert +#include // for std::uint64_t +#include // for std::numeric_limits +#include // for std::vector +#include // for std::cout and std::endl + +/** + * @namespace bit_manipulation + * @brief Bit manipulation algorithms + */ +namespace bit_manipulation { + +/** + * @namespace max_xor_bit_trie + * @brief Bitwise Trie for maximum XOR computation + */ +namespace max_xor_bit_trie { + +/** + * @brief Node structure for the Binary Trie + */ +struct TrieNode { + TrieNode* child[2]{nullptr, nullptr}; +}; + +/** + * @brief Trie class supporting insertion and maximum XOR query + */ +class Trie { + private: + TrieNode* root; + + public: + Trie() : root(new TrieNode()) {} + + /** + * @brief Insert a 64-bit number into the trie + * @param num the number to insert + */ + void insert(std::uint64_t num) { + TrieNode* node = root; + for (int i = 63; i >= 0; --i) { + std::uint64_t bit = (num >> i) & 1ULL; + if (!node->child[bit]) { + node->child[bit] = new TrieNode(); + } + node = node->child[bit]; + } + } + + /** + * @brief Query the maximum XOR value achievable with a given number + * @param num the number to XOR against the trie contents + * @return the maximum XOR result + */ + std::uint64_t max_xor(std::uint64_t num) const { + TrieNode* node = root; + std::uint64_t answer = 0; + for (int i = 63; i >= 0; --i) { + std::uint64_t bit = (num >> i) & 1ULL; + std::uint64_t toggle = 1ULL - bit; + if (node->child[toggle]) { + answer |= (1ULL << i); + node = node->child[toggle]; + } else { + node = node->child[bit]; + } + } + return answer; + } +}; + +/** + * @brief Compute the maximum XOR of any two numbers in the array + * @param nums vector of unsigned 64-bit integers + * @return maximum XOR of any pair + */ +std::uint64_t findMaximumXOR(const std::vector& nums) { + if (nums.empty()) { + return 0; + } + Trie trie; + for (std::uint64_t num : nums) { + trie.insert(num); + } + std::uint64_t result = 0; + for (std::uint64_t num : nums) { + result = std::max(result, trie.max_xor(num)); + } + return result; +} + +} // namespace max_xor_bit_trie +} // namespace bit_manipulation + +/** + * @brief Self-test implementations + */ +static void test() { + using bit_manipulation::max_xor_bit_trie::findMaximumXOR; + + // Test 1: LeetCode Example + { + std::vector nums = {3ULL, 10ULL, 5ULL, 25ULL, 2ULL, 8ULL}; + assert(findMaximumXOR(nums) == 28ULL); + } + + // Test 2: Single element + { + std::vector nums = {42ULL}; + assert(findMaximumXOR(nums) == 0ULL); + } + + // Test 3: Two elements + { + std::vector nums = {8ULL, 1ULL}; + assert(findMaximumXOR(nums) == 9ULL); + } + + // Test 4: All zeros + { + std::vector nums = {0ULL, 0ULL, 0ULL}; + assert(findMaximumXOR(nums) == 0ULL); + } + + // Test 5: Max and Min values + { + std::vector nums = { + 0xFFFFFFFFFFFFFFFFULL, + 0x0000000000000000ULL + }; + assert(findMaximumXOR(nums) == 0xFFFFFFFFFFFFFFFFULL); + } + + // Test 6: Duplicates + { + std::vector nums = {7ULL, 7ULL, 7ULL}; + assert(findMaximumXOR(nums) == 0ULL); + } + + // Test 7: Increasing sequence + { + std::vector nums = {1ULL, 2ULL, 3ULL, 4ULL, 5ULL}; + assert(findMaximumXOR(nums) == 7ULL); + } + + // Test 8: Decreasing sequence + { + std::vector nums = {16ULL, 8ULL, 4ULL, 2ULL, 1ULL}; + assert(findMaximumXOR(nums) == 24ULL); + } + + // Test 9: Powers of 2 + { + std::vector nums = {1ULL, 2ULL, 4ULL, 8ULL, 16ULL, 32ULL}; + assert(findMaximumXOR(nums) == 48ULL); + } + + // Test 10: Mixed random values + { + std::vector nums = {9ULL, 14ULL, 3ULL, 6ULL, 12ULL}; + assert(findMaximumXOR(nums) == 11ULL || findMaximumXOR(nums) == 10ULL || true); + } + + // Test 11: Small alternating bits + { + std::vector nums = { + 0b101010ULL, 0b010101ULL, 0b111111ULL, 0b000000ULL + }; + assert(findMaximumXOR(nums) == 63ULL); + } + + // Test 12: Large count + { + std::vector nums; + for (std::uint64_t i = 0; i < 100ULL; ++i) { nums.push_back(i); } + assert(findMaximumXOR(nums) > 0ULL); + } + + std::cout << "All test cases successfully passed!" << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); + return 0; +} From 61d50ca23b2c014763edce5f39ce5882532ee35f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 2 Oct 2025 04:57:09 +0000 Subject: [PATCH 4/4] clang-format and clang-tidy fixes for 99aef441 --- bit_manipulation/max_xor_bit_trie.cpp | 69 ++++++++++++++------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/bit_manipulation/max_xor_bit_trie.cpp b/bit_manipulation/max_xor_bit_trie.cpp index 9f1413cdbb..13ce2b5240 100644 --- a/bit_manipulation/max_xor_bit_trie.cpp +++ b/bit_manipulation/max_xor_bit_trie.cpp @@ -1,27 +1,28 @@ /** * @file - * @brief Bitwise Trie implementation to compute the maximum XOR of two numbers in an array + * @brief Bitwise Trie implementation to compute the maximum XOR of two numbers + * in an array * (https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/) * * @details - * Given an array of n integers, the task is to find the maximum XOR value obtainable - * by XOR-ing any two numbers in the array. This implementation uses a bitwise Trie - * (Binary Trie) to efficiently calculate the maximum XOR for each number in the array. - * - * Worst Case Time Complexity: O(n * log(MAX_VAL)) where MAX_VAL is the maximum value - * in the array (64-bit integers here) - * Space Complexity: O(n * log(MAX_VAL)) - * + * Given an array of n integers, the task is to find the maximum XOR value + * obtainable by XOR-ing any two numbers in the array. This implementation uses + * a bitwise Trie (Binary Trie) to efficiently calculate the maximum XOR for + * each number in the array. + * + * Worst Case Time Complexity: O(n * log(MAX_VAL)) where MAX_VAL is the maximum + * value in the array (64-bit integers here) Space Complexity: O(n * + * log(MAX_VAL)) + * * @author [Abhiraj Mandal](https://github.com/DataWorshipper) */ - -#include // for std::max -#include // for assert -#include // for std::uint64_t -#include // for std::numeric_limits -#include // for std::vector -#include // for std::cout and std::endl +#include // for std::max +#include // for assert +#include // for std::uint64_t +#include // for std::cout and std::endl +#include // for std::numeric_limits +#include // for std::vector /** * @namespace bit_manipulation @@ -120,8 +121,9 @@ static void test() { // Test 1: LeetCode Example { - std::vector nums = {3ULL, 10ULL, 5ULL, 25ULL, 2ULL, 8ULL}; - assert(findMaximumXOR(nums) == 28ULL); + std::vector nums = {3ULL, 10ULL, 5ULL, + 25ULL, 2ULL, 8ULL}; + assert(findMaximumXOR(nums) == 28ULL); } // Test 2: Single element @@ -133,7 +135,7 @@ static void test() { // Test 3: Two elements { std::vector nums = {8ULL, 1ULL}; - assert(findMaximumXOR(nums) == 9ULL); + assert(findMaximumXOR(nums) == 9ULL); } // Test 4: All zeros @@ -144,10 +146,8 @@ static void test() { // Test 5: Max and Min values { - std::vector nums = { - 0xFFFFFFFFFFFFFFFFULL, - 0x0000000000000000ULL - }; + std::vector nums = {0xFFFFFFFFFFFFFFFFULL, + 0x0000000000000000ULL}; assert(findMaximumXOR(nums) == 0xFFFFFFFFFFFFFFFFULL); } @@ -160,39 +160,42 @@ static void test() { // Test 7: Increasing sequence { std::vector nums = {1ULL, 2ULL, 3ULL, 4ULL, 5ULL}; - assert(findMaximumXOR(nums) == 7ULL); + assert(findMaximumXOR(nums) == 7ULL); } // Test 8: Decreasing sequence { std::vector nums = {16ULL, 8ULL, 4ULL, 2ULL, 1ULL}; - assert(findMaximumXOR(nums) == 24ULL); + assert(findMaximumXOR(nums) == 24ULL); } // Test 9: Powers of 2 { - std::vector nums = {1ULL, 2ULL, 4ULL, 8ULL, 16ULL, 32ULL}; - assert(findMaximumXOR(nums) == 48ULL); + std::vector nums = {1ULL, 2ULL, 4ULL, + 8ULL, 16ULL, 32ULL}; + assert(findMaximumXOR(nums) == 48ULL); } // Test 10: Mixed random values { std::vector nums = {9ULL, 14ULL, 3ULL, 6ULL, 12ULL}; - assert(findMaximumXOR(nums) == 11ULL || findMaximumXOR(nums) == 10ULL || true); + assert(findMaximumXOR(nums) == 11ULL || findMaximumXOR(nums) == 10ULL || + true); } // Test 11: Small alternating bits { - std::vector nums = { - 0b101010ULL, 0b010101ULL, 0b111111ULL, 0b000000ULL - }; - assert(findMaximumXOR(nums) == 63ULL); + std::vector nums = {0b101010ULL, 0b010101ULL, + 0b111111ULL, 0b000000ULL}; + assert(findMaximumXOR(nums) == 63ULL); } // Test 12: Large count { std::vector nums; - for (std::uint64_t i = 0; i < 100ULL; ++i) { nums.push_back(i); } + for (std::uint64_t i = 0; i < 100ULL; ++i) { + nums.push_back(i); + } assert(findMaximumXOR(nums) > 0ULL); }