Count of distinct XORs formed by rearranging two Binary strings

06 Jun, 2022
Given two binary strings A and B of equal length N, the task is to find the number of distinct XORs possible by arbitrarily reordering the two binary strings. Since the number can be large enough, find the number modulo 109 + 7
Examples: 
Input: A = “00”, B = “01” Output: 2 Explanation: There are two possible results by rearranging the digits of the string B. They are: “10” and “01”
Input: A = “010”, B = “100” Output: 4 Explanation: There are four possible results possible by rearranging the digits of both the strings. They are: “000”, “110”, “011”, “101” 
Approach:  
Since we know that
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
Therefore, to get an XOR value as ‘1’ at any index of the result string, the input strings must have odd number of 1s at that index.
Now, we will try to rearrange the Binary strings in a way, that maximum number of indices have an odd number of 1s at them. This can be visualized by the following example:
Therefore, from the above observation, the idea is to find the minimum and the maximum number of 1’s possible by reordering the strings. To find the Maximum ‘1’s: The maximum ‘1’s in the result would occur when maximum {0, 1} and {1, 0} pairs are formed. Therefore,
To find the Maximum ‘1’s: The maximum ‘1’s in the result would occur when maximum {0, 1} and {1, 0} pairs are formed. Therefore,
Maximum number of {0, 1} pairs = minimum(count of ‘0’ in A, count of ‘1’ in B) Maximum number of {1, 0} pairs = minimum(count of ‘1’ in A, count of ‘0’ in B)Therefore, Maximum number of ‘1’s in the XOR = Maximum number of {0, 1} pairs + Maximum number of {1, 0} pairs  
To find the Minimum ‘1’s: This case can be seen as the converse of the maximum number of ‘0’s in the result. Similarly, the maximum ‘0’s in the result would occur when maximum {0, 0} and {1, 1} pairs are formed. Therefore,
Maximum number of {0, 0} pairs = minimum(count of ‘0’ in A, count of ‘0’ in B) Maximum number of {1, 1} pairs = minimum(count of ‘1’ in A, count of ‘1’ in B) Maximum number of ‘0’s in the XOR = Maximum number of {0, 0} pairs + Maximum number of {1, 1} pairsTherefore, Minimum number of ‘1’s in the XOR = N – Maximum number of ‘0’s in the XOR  
All the combinations of 1’s can be formed in between these two numbers (minimum and maximum) with the difference of 2.
Finally, the total number of possible ways to get the result can be calculated by the number of combinations from the minimum number of 1’s and the maximum number of 1’s with a step of 2.
Below is the implementation of the above approach: 
C++14
Java
Python3
C#
Javascript
// C++ program to find the number of// distinct XORs formed by rearranging// two binary strings#include <bits/stdc++.h> using namespace std; // function to compute modulo powerlong long power(long long a, long long b, long long mod){    long long aa = 1;    while(b)    {         if(b&1)        {            aa = aa * a;            aa %= mod;        }        a = a * a;        a %= mod;        b /= 2;    }     return aa;} // Function to calculate nCr % p// over a rangelong long nCrRangeSum(long long n, long long r1,                    long long r2, long long p){     // Initialize the numerator    // and denominator    long long num = 1, den = 1;     // Initialize the sum    long long sum = 0;     // nC0 is 1    if (r1 == 0)        sum += 1;     // Traversing till the range    for (int i = 0; i < r2; i++)    {         // Computing the numerator        num = (num * (n - i)) % p;         // Computing the denominator        den = (den * (i + 1)) % p;         // If 'i' lies between the given range        // and is at an even long long interval from        // the starting range because        // the combinations at a step of 2        // is required        if(i - r1 >= -1 and (i - r1 + 1) % 2 == 0)        {             // Computing nCr and adding the value            // sum            sum += (num * power(den, p - 2, p)) % p;            sum %= p;        }        }    return sum;} // Function to find the number of// distinct XORs formed by// rearranging two binary stringsint compute(string A, string B, int N){     // Initializing the count variable    // to 0    int c0A = 0, c1A = 0, c0B = 0, c1B = 0;     // Iterating through A    for (char c:A) {         // Increment the c1A variable        // if the current element is 1        if (c == '1')            c1A += 1;         // Increment the c0A variable        // if the current element is 0        else if (c == '0')            c0A += 1;        }     // Iterating through B    for (char c:B){         // Increment the c1B variable        // if the current element is 1        if (c == '1')            c1B += 1;         // Increment the c0A variable        // if the current element is 0        else if (c == '0')            c0B += 1;        }     // Finding the minimum number of '1's in the XOR    // and the maximum number of '1's in the XOR    int max1xor = min(c0A, c1B) + min(c1A, c0B);    int min1xor = N - min(c0B, c0A) - min(c1A, c1B);     // Compute the number of combinations between    // the minimum number of 1's and the maximum    // number of 1's and perform % with 10^9 + 7    int ans = nCrRangeSum(N, min1xor, max1xor, 1000000000 + 7);     // Return the answer    return ans;} // Driver codeint main(){    long long N = 3;    string A = "010";    string B = "100";         cout << compute(A, B,N);    return 0;} // This code is contributed by mohit kumar 29
// JAVA program to find the number of// distinct Bitwise XORs formed by rearranging// two binary strings class GFG{    // function to compute modular exponentiation    // i.e. to find (a^b) % mod    static long mod_power(long a, long b,                          long mod)    {        long result = 1l;        while(b > 0)        {            if((b&1) == 0) // b is even            {                result = a * a;                a %= mod;                b /= 2;            }            else // b is odd            {                result = result * a;                result %= mod;            }        }        return result;    }     // method to evaluate nCr modulo p    // over an interval    static long nCr_RangeSum(long n, long r1,                            long r2, long p)    {         // initializing numerator        // and denominator        long num = 1, den = 1;         // initialize the sum        long sum = 0l;         // nC0 is 1        if(r1 == 0)            sum += 1l;         // Iterating through the range        for(int i = 0; i < r2; i++)        {             // computing the numerator            num = (num * (n - i)) % p;                         // computing the denominator            den = (den * (i + 1)) % p;             // If 'i' lies between the given range            // and is at an even interval from             // the starting range because             // the combinations at a step of 2             // is required            if(i - r1 >= -1 && (i - r1 + 1) % 2 == 0)            {                // Computing nCr and adding the value                // to the sum                  sum += (num * mod_power(den, p - 2, p)) % p;                sum %= p;            }        }        return sum;    }         // method to find the number of    // distinct XORs formed by    // rearrangement of two binary strings    static long compute(String A, String B, int N)    {        // Initializing the counter variables        // to 0        int c0A = 0, c1A = 0, c0B = 0, c1B = 0;         // Iterating through A's characters        for (char c : A.toCharArray())        {             // Increment the c1A variable            // if the current element is 1            if (c == '1')                c1A += 1;             // Increment the c0A variable            // if the current element is 0            else if (c == '0')                c0A += 1;            }         // Iterating through B's characters        for (char c : B.toCharArray())        {             // Increment the c1B variable            // if the current element is 1            if (c == '1')                c1B += 1;             // Increment the c0A variable            // if the current element is 0            else if (c == '0')                c0B += 1;        }        // Finding the minimum number of '1's in the XOR        // and the maximum number of '1's in the XOR        int max1xor = Math.min(c0A, c1B) + Math.min(c1A, c0B);        int min1xor = N - Math.min(c0B, c0A) - Math.min(c1A, c1B);         // Compute the number of combinations between        // the minimum number of 1's and the maximum        // number of 1's and perform modulo with 10^9 + 7        long ans =  nCr_RangeSum(N, min1xor, max1xor, 1000000000 + 7);         // Return the answer        return ans;    }     // Driver code    public static void main(String[] args)    {        int N = 3; // length of each string                 String A = "010";        String B = "100";                 System.out.print(compute(A, B, N));    }} // This Code is contributed by Soumitri Chattopadhyay.
# Python3 program to find the number of# distinct XORs formed by rearranging# two binary strings # Function to calculate nCr % p# over a rangedef nCrRangeSum(n, r1, r2, p):     # Initialize the numerator    # and denominator    num = den = 1     # Initialize the sum    sum = 0         # nC0 is 1    if r1 == 0:        sum += 1     # Traversing till the range    for i in range(r2):         # Computing the numerator        num = (num * (n - i)) % p         # Computing the denominator        den = (den * (i + 1)) % p         # If 'i' lies between the given range        # and is at an even interval from        # the starting range because        # the combinations at a step of 2        # is required        if(i - r1 >= -1 and (i - r1 + 1) % 2 == 0):             # Computing nCr and adding the value            # sum            sum += (num * pow(den, p - 2, p)) % p            sum %= p    return sum # Function to find the number of# distinct XORs formed by# rearranging two binary stringsdef compute(A, B):     # Initializing the count variable    # to 0    c0A = c1A = c0B = c1B = 0     # Iterating through A    for c in A:         # Increment the c1A variable        # if the current element is 1        if c == '1':            c1A += 1         # Increment the c0A variable        # if the current element is 0        elif c == '0':            c0A += 1     # Iterating through B    for c in B:         # Increment the c1B variable        # if the current element is 1        if c == '1':            c1B += 1         # Increment the c0A variable        # if the current element is 0        elif c == '0':            c0B += 1     # Finding the minimum number of '1's in the XOR    # and the maximum number of '1's in the XOR    max1xor = min(c0A, c1B) + min(c1A, c0B)    min1xor = N - min(c0B, c0A) - min(c1A, c1B)         # Compute the number of combinations between    # the minimum number of 1's and the maximum    # number of 1's and perform % with 10^9 + 7    ans = nCrRangeSum(N, min1xor, max1xor, 10**9 + 7)     # Return the answer    return ans # Driver codeif __name__ == "__main__":     N = 3    A = "010"    B = "100"     print(compute(A, B))
// C# program to find the number of // distinct Bitwise XORs formed by// rearranging two binary stringsusing System; class GFG{     // Function to compute modular exponentiation// i.e. to find (a^b) % mod static long mod_power(long a, long b,                      long mod){    long result = 1;         while (b > 0)    {        if ((b & 1) == 0) // b is even        {            result = a * a;            a %= mod;            b /= 2;        }        else // b is odd        {            result = result * a;            result %= mod;        }    }    return result;} // Function to evaluate nCr modulo p// over an intervalstatic long nCr_RangeSum(long n, long r1,                          long r2, long p){         // Initializing numerator     // and denominator    long num = 1, den = 1;     // Initialize the sum     long sum = 0;     // nC0 is 1    if (r1 == 0)        sum += 1;     // Iterating through the range    for(int i = 0; i < r2; i++)    {                 // Computing the numerator        num = (num * (n - i)) % p;                   // Computing the denominator        den = (den * (i + 1)) % p;          // If 'i' lies between the given range         // and is at an even interval from          // the starting range because          // the combinations at a step of 2          // is required         if (i - r1 >= -1 && (i - r1 + 1) % 2 == 0)         {                         // Computing nCr and adding the value             // to the sum               sum += (num * mod_power(                  den, p - 2, p)) % p;             sum %= p;         }    }    return sum;}   // Function to find the number of distinct// XORs formed by rearrangement of two// binary stringsstatic long compute(string A, string B, int N){         // Initializing the counter variables     // to 0     int c0A = 0, c1A = 0, c0B = 0, c1B = 0;      // Iterating through A's characters     foreach(char c in A)     {                  // Increment the c1A variable         // if the current element is 1         if (c == '1')             c1A += 1;          // Increment the c0A variable         // if the current element is 0         else if (c == '0')             c0A += 1;     }      // Iterating through B's characters     foreach(char c in B)    {                  // Increment the c1B variable         // if the current element is 1         if (c == '1')             c1B += 1;          // Increment the c0A variable         // if the current element is 0         else if (c == '0')             c0B += 1;     }          // Finding the minimum number of    // '1's in the XOR and the maximum    // number of '1's in the XOR     int max1xor = Math.Min(c0A, c1B) +                  Math.Min(c1A, c0B);     int min1xor = N - Math.Min(c0B, c0A) -                      Math.Min(c1A, c1B);      // Compute the number of combinations    // between the minimum number of 1's    // and the maximum number of 1's and    // perform modulo with 10^9 + 7     long ans =  nCr_RangeSum(N, min1xor,                 max1xor, 1000000000 + 7);     // Return the answer     return ans; } // Driver codestatic public void Main(){         // Length of each string    int N = 3;           string A = "010";     string B = "100";            Console.WriteLine(compute(A, B, N));}} // This code is contributed by offbeat
// JavaScript program to find the number of// distinct XORs formed by rearranging// two binary strings // function to compute modulo powerfunction power(a, b, mod){    var aa = 1n;    while (b) {         if (BigInt(b) & 1n) {            aa = aa * a;            aa %= mod;        }        a = a * a;        a %= mod;        b = Math.floor(Number(BigInt(b) / 2n));    }     return aa;} // Function to calculate nCr % p// over a rangefunction nCrRangeSum(n, r1, r2, p){     // Initialize the numerator    // and denominator    var num = 1n;    var den = 1n;     // Initialize the sum    var sum = 0n;     // nC0 is 1    if (r1 == 0)        sum += 1n;     // Traversing till the range    for (var i = 0; i < r2; i++) {         // Computing the numerator        num = (num * (BigInt(n) - BigInt(i))) % p;         // Computing the denominator        den = BigInt(den * (BigInt(i) + 1n)) % p;         // If 'i' lies between the given range        // and is at an even long long interval from        // the starting range because        // the combinations at a step of 2        // is required        if (i - r1 >= -1 && (i - r1 + 1) % 2 == 0) {             // Computing nCr and adding the value            // sum            sum += BigInt(num * power(den, p - 2n, p)) % p;            sum %= p;        }    }    return Number(sum);} // Function to find the number of// distinct XORs formed by// rearranging two binary stringsfunction compute(A, B, N){     // Initializing the count variable    // to 0    var c0A = 0;    var c1A = 0;    var c0B = 0;    var c1B = 0;     // Iterating through A    for (var c of A) {         // Increment the c1A variable        // if the current element is 1        if (c == '1')            c1A += 1;         // Increment the c0A variable        // if the current element is 0        else if (c == '0')            c0A += 1;    }     // Iterating through B    for (var c of B) {         // Increment the c1B variable        // if the current element is 1        if (c == '1')            c1B += 1;         // Increment the c0A variable        // if the current element is 0        else if (c == '0')            c0B += 1;    }     // Finding the minimum number of '1's in the XOR    // and the maximum number of '1's in the XOR    var max1xor = Math.min(c0A, c1B) + Math.min(c1A, c0B);    var min1xor        = N - Math.min(c0B, c0A) - Math.min(c1A, c1B);     // Compute the number of combinations between    // the minimum number of 1's and the maximum    // number of 1's and perform % with 10^9 + 7    var ans = nCrRangeSum(N, min1xor, max1xor,                          BigInt(1000000000 + 7));     // Return the answer    return ans;} // Driver codevar N = 3;var A = "010";var B = "100"; // Function callconsole.log(compute(A, B, N)); // This code is contributed by phasing17
4
 
mohit kumar 29
chatterjee0soumitri
offbeat
phasing17
array-rearrange
binary-string
Bitwise-XOR
Permutation and Combination
Arrays
Bit Magic
Combinatorial
Mathematical
Strings
Write From Home
Arrays
Strings
Mathematical
Bit Magic
Combinatorial
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Multidimensional Arrays in Java
Linear Search
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Bitwise Operators in C/C++
Left Shift and Right Shift Operators in C/C++
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Count set bits in an integer
How to swap two numbers without using a temporary variable?