How to efficiently enumerate a Restricted Gray Code? - c

I'm looking for an algorithm which enumeration all binary strings of length n in a Gray code manner, with the restriction that all strings have at most hamming weight <= k. For example n=4,k=2:
0000
0001
0011
0010
0110
---- skipped
0101
0100
1100
---- skipped
---- skipped
---- skipped
1010
---- skipped
1001
1000
n and k are known constants. The classic Gray code has two very important features: One can simply compute the i-th element a as i ^ (i >> 1) and given the i-th element a one can compute the next one as a ^ ctz(i+1), where ctz returns the number of trailing zeros (gcc buildin function).
So im looking for something like a "restricted" Gray code, with this features, which should be easy and fast computable.
The most straight forward solution would be to insert a popcount into the loop, which branches if a code word has the wrong weight. Sadly this is far to expensive in my setting: n = 45-50 and k = 15-18.

I'm not sure this is what you're looking for but let's give it a try...
The ith element of the code is calculated using the formula you mentioned:
G[i] = i ^ (i >> 1). Another feature of the Gray code is that any element is different from the previous one in a single place, therefore the bitwise xor operation between an element G[i] and its predecessor G[i-1], will result in a single bit being equal to one, at the position d at which the two element are different from each other. For instance G[i] ^ G[i-1] = 0101 ^ 0111 = 0010. Now the bitwise and operation between this result and the element G[i], will give 0 only if G[i] has a 0 at position d, otherwise the result will be equal to 2 ^ d, with d starting from 0. So, if (G[i] ^ G[i-1]) & G[i] == 0 it means that at the only place the two elements differ, G[i] has a 0 instead of a 1 and therefore its Hamming weight is 1 less than the one of G[i-1]. On the other hand if (G[i] ^ G[i-1]) & G[i] != 0, the Hamming weight of G[i] is 1 more than the one of G[i-1]. In order to know the Hamming weight of an element you just have to keep track of the weight of the previous elements. Starting from 0 and adding or subtracting 1 each time based on the result of (G[i] ^ G[i-1]) & G[i]. Hopefully this is somewhat comprehensible...
At a first glance I would say that this should perform better than the version using popcount but it may also depend on how operations are implemented both in software and hardware. I'm not particularly expert in this regard.
Here is the code:
#include <stdio.h>
#include <stdint.h>
void printBinary(uint64_t number); // function for printing the variable in binary
int main()
{
int k = 18; // max Hamming weight
int iter = 1000; // number of codes to check
uint64_t Gnew = 0;
uint64_t Gold = 0;
int i = 0;
int count = 0; // counter holding the Hamming weight of the current element
printBinary(Gold); // print the first element (0)
for (i = 1; i < iter; i++){
Gnew = i ^ (i >> 1); // generate the ith element of the Gray code
if (((Gnew ^ Gold) & Gnew) != 0){ // checks if the new element has one 1 more than the previous
count++; // and increases the counter
}else{ // or has one 1 less
count--; // and decreases the counter
}
if(count <= k){ // if element has weight smaller or equal to k print the element
printBinary(Gnew);
}
Gold = Gnew;
}
return 0;
}
void printBinary(uint64_t number) // from https://stackoverflow.com/questions/47326588/c-print-unsigned-int-in-a-binary-base
// with some modifications
{
int i;
for(i = 63; i >= 0; i--){
if(number >> i & 0x1){
putchar('1');
}else{
putchar('0');
}
}
putchar('\n');
return;
}

Related

how to find if M is actually an output of 2power(2n) + 1 in C program

I have a tricky requirement in project asking to write function which returns a value 1 (0 otherwise) if given an integer representable as 22n+1. Where n is any non-negative integer.
int find_pow_2n_1(int M);
for e.g: return 1, when M=5 since 5 is output when n=1 -> 21*2+1 .
I am trying to evaluate the equation but it results in log function, not able to find any kind of hint while browsing in google as well .
Solution
int find_pow_2n_1(int M)
{
return 1 < M && !(M-1 & M-2) && M % 3;
}
Explanation
First, we discard values less than two, as we know the first matching number is two.
Then M-1 & M-2 tests whether there is more than one bit set in M-1:
M-1 cannot have zero bits set, since M is greater than one, so M-1 is not zero.
If M-1 has one bit set, then that bit is zero in M-2 and all lower bits are set, so M-1 and M-2 have no set bits in common, so M-1 & M-2 is zero.
If M-1 has more than one bit set, then M-2 has the lowest set bit cleared, but higher set bits remain set. So M-1 and M-2 have set bits in common, so M-1 & M-2 is non-zero.
So, if the test !(M-1 & M-2) passes, we know M-1 is a power of two. So M is one more than a power of two.
Our remaining concern is whether that is an even power of two. We can see that when M is an even power of two plus one, its remainder modulo three is two, whereas when M is an odd power of two plus one, its remainder modulo three is zero:
Remainder of 20+1 = 2 modulo 3 is 2.
Remainder of 21+1 = 3 modulo 3 is 0.
Remainder of 22+1 = 5 modulo 3 is 2.
Remainder of 23+1 = 9 modulo 3 is 0.
Remainder of 24+1 = 17 modulo 3 is 2.
Remainder of 25+1 = 33 modulo 3 is 0.
…
Therefore, M % 3, which tests whether the remainder of M modulo three is non-zero, tests whether M-1 is an even power of two.
There are only a few numbers with that property: make a table lookup array :-)
$ bc
for(n=0;n<33;n++)2^(2*n)+1
2
5
17
65
257
1025
4097
16385
65537
262145
1048577
4194305
16777217
67108865
268435457
1073741825
4294967297
17179869185
68719476737
274877906945
1099511627777
4398046511105
17592186044417
70368744177665
281474976710657
1125899906842625
4503599627370497
18014398509481985
72057594037927937
288230376151711745
1152921504606846977
4611686018427387905
18446744073709551617
Last number above is 2^64 + 1, probably will not fit an int in your implementation.
All proposed solutions are way too complicated or bad in performance. Try the simpler one:
static int is_power_of_2(unsigned long n)
{
return (n != 0 && ((n & (n - 1)) == 0));
}
static int is_power_of_2n(unsigned long n)
{
return is_power_of_2(n) && (__builtin_ffsl(n) & 1);
}
int main(void)
{
int x;
for (x = -3; x < 20; x++)
printf("Is %d = 2^2n + 1? %s\n", x, is_power_of_2n(x - 1) ? "Yes" : "no");
return 0;
}
Implementing __builtin_ffsl(), if you are using ancient compiler, I leave it as a homework (it can be done without tables or divisions).
Example: https://wandbox.org/permlink/gMrzZqhuP4onF8ku
While commenting on #Lundin's comment I realized that you may read a very nice set of bit twiddling hacks from Standford University.
UPDATE. As #grenix noticed the initial question was about the direct check, it may be done with the above code by introducing an additional wrapper, so nothing basically changes:
...
static int is_power_of_2n_plus_1(unsigned long n)
{
return is_power_of_2n(n - 1);
}
int main(void)
{
int x;
for (x = -3; x < 20; x++)
printf("Is %d = 2^2n + 1? %s\n", x, is_power_of_2n_plus_1(x) ? "Yes" : "no");
return 0;
}
Here I am leaving you a pseudocode (or a code that I haven't tested) which I think could help you think of the way to handle your problem :)
#include <math.h>
#include <stdlib.h>
#define EPSILON 0.000001
int find_pow_2n_1(int M) {
M--; // M = pow 2n now
double val = log2(M); // gives us 2n
val /= 2; // now we have n
if((val * 10) / 10 - val) <= EPSILON) return 1; // check whether n is an integer or not
else return 0;
}

Find 2 repeating elements in given array

Given an array with n+2 elements, all elements in the array are in the range 1 to n and all elements occur only once except two elements which occur twice.
Find those 2 repeating numbers. For example, if the array is [4, 2, 4, 5, 2, 3, 1], then n is 5, there are n+2 = 7 elements with all elements occurring only once except 2 and 4.
So my question is how to solve the above problem using XOR operation. I have seen the solution on other websites but I'm not able to understand it. Please consider the following example:
arr[] = {2, 4, 7, 9, 2, 4}
XOR every element. xor = 2^4^7^9^2^4 = 14 (1110)
Get a number which has only one set bit of the xor. Since we can easily get the rightmost set bit, let us use it.
set_bit_no = xor & ~(xor-1) = (1110) & ~(1101) = 0010. Now set_bit_no will have only set as rightmost set bit of xor.
Now divide the elements in two sets and do xor of elements in each set, and we get the non-repeating elements 7 and 9.
Yes, you can solve it with XORs. This answer expands on Paulo Almeida's great comment.
The algorithm works as follows:
Since we know that the array contains every element in the range [1 .. n], we start by XORing every element in the array together and then XOR the result with every element in the range [1 .. n]. Because of the XOR properties, the unique elements cancel out and the result is the XOR of the duplicated elements (because the duplicate elements have been XORed 3 times in total, whereas all the others were XORed twice and canceled out). This is stored in xor_dups.
Next, find a bit in xor_dups that is a 1. Again, due to XOR's properties, a bit set to 1 in xor_dups means that that bit is different in the binary representation of the duplicate numbers. Any bit that is a 1 can be picked for the next step, my implementation chooses the least significant. This is stored in diff_bit.
Now, split the array elements into two groups: one group contains the numbers that have a 0 bit on the position of the 1-bit that we picked from xor_dups. The other group contains the numbers that have a 1-bit instead. Since this bit is different in the numbers we're looking for, they can't both be in the same group. Furthermore, both occurrences of each number go to the same group.
So now we're almost done. Consider the group for the elements with the 0-bit. XOR them all together, then XOR the result with all the elements in the range [1..n] that have a 0-bit on that position, and the result is the duplicate number of that group (because there's only one number repeated inside each group, all the non-repeated numbers canceled out because each one was XORed twice except for the repeated number which was XORed three times).
Rinse, repeat: for the group with the 1-bit, XOR them all together, then XOR the result with all the elements in the range [1..n] that have a 1-bit on that position, and the result is the other duplicate number.
Here's an implementation in C:
#include <assert.h>
void find_two_repeating(int arr[], size_t arr_len, int *a, int *b) {
assert(arr_len > 3);
size_t n = arr_len-2;
int i;
int xor_dups = 0;
for (i = 0; i < arr_len; i++)
xor_dups ^= arr[i];
for (i = 1; i <= n; i++)
xor_dups ^= i;
int diff_bit = xor_dups & -xor_dups;
*a = 0;
*b = 0;
for (i = 0; i < arr_len; i++)
if (arr[i] & diff_bit)
*a ^= arr[i];
else
*b ^= arr[i];
for (i = 1; i <= n; i++)
if (i & diff_bit)
*a ^= i;
else
*b ^= i;
}
arr_len is the total length of the array arr (the value of n+2), and the repeated entries are stored in *a and *b (these are so-called output parameters).

How can I maximize XOR sum of subset of given array of integer? [duplicate]

I have to find maximum value of exclusive xor among the elements of subsets of an array. I have to check every subset of the array and the subset which will yield maximum xor will be the answer.
For exapmle- let F(S) denote the fuction which takes xor over all elements of subset S of array P={1,2,3,4}
F({1,2}) = 3
F({1,3}) = 2
F({1,2,3}) = 0
F({1,4}) = 5
F({2,3}) = 1
F({2,4}) = 6
F({3,4}) = 7
F({2,3,4}) = 5
F({1,2,3,4}) = 4`
Maximum of them is 7. Hence the answer is 7.(There are other subsets but they are not worth considering). If you are about to tell me about Gaussian Elimination method, I've read that somewhere on MSE but it was not at all clear to me.
If gauss elimination is the only answer than please elaborate that to me or is there some method/algorithm I don't know of?
Gaussian Elimination is what you need.
For example : 3 numbers {9, 8, 5}
First sort them in decreasing order and convert them into binary :
9 : 1001
8 : 1000
5 : 0101
Observe the 1st number. Highest bit is 4.
Now check 4th bit of the 1st number (9). As it is 1, xor the number with the rest of the numbers where 4th bit is 1.
9 : 1001
1 : 0001 > changed
5 : 0101
Now check 3rd bit of 2nd number (1). As it is 0, check rest of the below numbers where 3rd bit is 1.
Number 5 has 1 in 3rd bit. Swap them :
9 : 1001
5 : 0101 > swapped
1 : 0001 >
Now xor 5 with the rest of the numbers where 3rd bit is 1. Here none exists. So there will be no change.
Now check 2nd bit of 3rd number (1). As it is 0 and there is no other number below where 2nd bit is 1, so there will be no change.
Now check 1st bit of 3rd number (1). As it is 1, change the rest of the numbers where 1st bit is 1.
8 : 1000 > changed
4 : 0100 > changed
1 : 0001
No more bit left to consider :)
Now xor the whole remaining array {8 ^ 4 ^ 1} = 13
So 13 is the solution :)
That's pretty much how you solve the problem using Gaussian Elimination :)
Here is my C++ implementation :
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
ull check_bit(ull N,int POS){return (N & (1ULL<<POS));}
vector<ull>v;
ull gaussian_elimination()
{
int n=v.size();
int ind=0; // Array index
for(int bit=log2(v[0]);bit>=0;bit--)
{
int x=ind;
while(x<n&&check_bit(v[x],bit)==0)
x++;
if(x==n)
continue; // skip if there is no number below ind where current bit is 1
swap(v[ind],v[x]);
for(int j=0;j<n;j++)
{
if(j!=ind&&check_bit(v[j],bit))
v[j]^=v[ind];
}
ind++;
}
ull ans=v[0];
for(int i=1;i<n;i++)
ans=max(ans,ans^v[i]);
return ans;
}
int main()
{
int i,j,k,l,m,n,t,kase=1;
scanf("%d",&n);
ull x;
for(i=0;i<n;i++)
{
cin>>x;
v.push_back(x);
}
sort(v.rbegin(),v.rend());
cout<<gaussian_elimination()<<"\n";
return 0;
}
I guess that you're referring to this question.
Gaussian Elimination is the algorithm description that I would expect from the math site. This is what the algorithm looks like in Python.
def max_xor(iterable):
array = list(iterable) # make it a list so that we can iterate it twice
if not array: # special case the empty array to avoid an empty max
return 0
x = 0
while True:
y = max(array)
if y == 0:
return x
# y has the leading 1 in the array
x = max(x, x ^ y)
# eliminate
array = [min(z, z ^ y) for z in array]

Two elements in array whose xor is maximum

Given an array of integers ,You have to find two elements whose XOR is maximum.
There is naive approach --just by picking each element and xoring with other elements and then comparing the results to find the pair.
Other than this ,Is there any efficient algorithm?
I think I have a O(n lg U) algorithm for this, where U is the largest number. The idea is similar to user949300's, but with a bit more detail.
The intuition is as follows. When you're XORing two numbers together, to get the maximum value, you want to have a 1 at the highest possible position, and then of the pairings that have a 1 at this position, you want a pairing with a 1 at the next possible highest position, etc.
So the algorithm is as follows. Begin by finding the highest 1 bit anywhere in the numbers (you can do this in time O(n lg U) by doing O(lg U) work per each of the n numbers). Now, split the array into two pieces - one of the numbers that have a 1 in that bit and the group with 0 in that bit. Any optimal solution must combine a number with a 1 in the first spot with a number with a 0 in that spot, since that would put a 1 bit as high as possible. Any other pairing has a 0 there.
Now, recursively, we want to find the pairing of numbers from the 1 and 0 group that has the highest 1 in them. To do this, of these two groups, split them into four groups:
Numbers starting with 11
Numbers starting with 10
Numbers starting with 01
Numbers starting with 00
If there are any numbers in the 11 and 00 group or in the 10 and 01 groups, their XOR would be ideal (starting with 11). Consequently, if either of those pairs of groups isn't empty, recursively compute the ideal solution from those groups, then return the maximum of those subproblem solutions. Otherwise, if both groups are empty, this means that all the numbers must have the same digit in their second position. Consequently, the optimal XOR of a number starting with 1 and a number starting with 0 will end up having the next second bit cancel out, so we should just look at the third bit.
This gives the following recursive algorithm that, starting with the two groups of numbers partitioned by their MSB, gives the answer:
Given group 1 and group 0 and a bit index i:
If the bit index is equal to the number of bits, return the XOR of the (unique) number in the 1 group and the (unique) number in the 0 group.
Construct groups 11, 10, 01, and 00 from those groups.
If group 11 and group 00 are nonempty, recursively find the maximum XOR of those two groups starting at bit i + 1.
If group 10 and group 01 are nonempty, recursively find the maximum XOR of those two groups, starting at bit i + 1.
If either of the above pairings was possible, then return the maximum pair found by the recursion.
Otherwise, all of the numbers must have the same bit in position i, so return the maximum pair found by looking at bit i + 1 on groups 1 and 0.
To start off the algorithm, you can actually just partition the numbers from the initial group into two groups - numbers with MSB 1 and numbers with MSB 0. You then fire off a recursive call to the above algorithm with the two groups of numbers.
As an example, consider the numbers 5 1 4 3 0 2. These have representations
101 001 100 011 000 010
We begin by splitting them into the 1 group and the 0 group:
101 100
001 011 000 010
Now, we apply the above algorithm. We split this into groups 11, 10, 01, and 00:
11:
10: 101 100
01: 011 010
00: 000 001
Now, we can't pair any 11 elements with 00 elements, so we just recurse on the 10 and 01 groups. This means we construct the 100, 101, 010, and 011 groups:
101: 101
100: 100
011: 011
010: 010
Now that we're down to buckets with just one element in them, we can just check the pairs 101 and 010 (which gives 111) and 100 and 011 (which gives 111). Either option works here, so we get that the optimal answer is 7.
Let's think about the running time of this algorithm. Notice that the maximum recursion depth is O(lg U), since there are only O(log U) bits in the numbers. At each level in the tree, each number appears in exactly one recursive call, and each of the recursive calls does work proportional to the total number of numbers in the 0 and 1 groups, because we need to distribute them by their bits. Consequently, there are O(log U) levels in the recursion tree, and each level does O(n) work, giving a total work of O(n log U).
Hope this helps! This was an awesome problem!
This can be solved in O(NlogN) time complexity using Trie.
Construct a trie. For each integer key, each node of the trie will hold every bit(0 or 1) starting from most significant bit.
Now for each arr[i] element of arr[0, 1, ..... N]
Perform query to retrieve the maximum xor value possible for arr[i]. We know xor of different type of bits(0 ^ 1 or 1 ^ 0) is always 1. So during query for each bit, try to traverse node holding opposite bit. This will make that particular bit 1 result in maximizing xor value. If there is no node with opposite bit, only then traverse the same bit node.
After query, insert arr[i] into trie.
For each element, keep track the maximum Xor value possible.
During walking through each node, build the other key for which the Xor is being maximized.
For N elements, we need one query(O(logN)) and one insertion(O(logN)) for each element. So the overall time complexity is O(NlogN).
You can find nice pictorial explanation on how it works in this thread.
Here is C++ implementation of the above algorithm:
const static int SIZE = 2;
const static int MSB = 30;
class trie {
private:
struct trieNode {
trieNode* children[SIZE];
trieNode() {
for(int i = 0; i < SIZE; ++i) {
children[i] = nullptr;
}
}
~trieNode() {
for(int i = 0; i < SIZE; ++i) {
delete children[i];
children[i] = nullptr;
}
}
};
trieNode* root;
public:
trie(): root(new trieNode()) {
}
~trie() {
delete root;
root = nullptr;
}
void insert(int key) {
trieNode* pCrawl = root;
for(int i = MSB; i >= 0; --i) {
bool bit = (bool)(key & (1 << i));
if(!pCrawl->children[bit]) {
pCrawl->children[bit] = new trieNode();
}
pCrawl = pCrawl->children[bit];
}
}
int query(int key, int& otherKey) {
int Xor = 0;
trieNode *pCrawl = root;
for(int i = MSB; i >= 0; --i) {
bool bit = (bool)(key & (1 << i));
if(pCrawl->children[!bit]) {
pCrawl = pCrawl->children[!bit];
Xor |= (1 << i);
if(!bit) {
otherKey |= (1 << i);
} else {
otherKey &= ~(1 << i);
}
} else {
if(bit) {
otherKey |= (1 << i);
} else {
otherKey &= ~(1 << i);
}
pCrawl = pCrawl->children[bit];
}
}
return Xor;
}
};
pair<int, int> findMaximumXorElements(vector<int>& arr) {
int n = arr.size();
int maxXor = 0;
pair<int, int> result;
if(n < 2) return result;
trie* Trie = new trie();
Trie->insert(0); // insert 0 initially otherwise first query won't find node to traverse
for(int i = 0; i < n; i++) {
int elem = 0;
int curr = Trie->query(arr[i], elem);
if(curr > maxXor) {
maxXor = curr;
result = {arr[i], elem};
}
Trie->insert(arr[i]);
}
delete Trie;
return result;
}
Ignoring the sign bit, one of the values must be one of the values with the highest significant bit set. Unless all the values have that bit set, in which case you go to the next highest significant bit that isn't set in all the values. So you could pare down the possibilities for the 1st value by looking at the HSB. For example, if the possibilities are
0x100000
0x100ABC
0x001ABC
0x000ABC
The 1st value of the max pair must be either 0x100000 or 0x10ABCD.
#internal Server Error I don't think smallest is necessarily correct. I don't have a great idea for paring down the 2nd value. Just any value that isn't in the list of possible 1st values. In my example, 0x001ABC or 0x000ABC.
A very interesting problem!
Here is my idea:
First build a binary tree from all the numbers by using the binary
representation and sort them into the tree most significant bit first
(add leading zeros to match the longest number). When done each path
from the root to any leaf represents one number from the original
set.
Let a and b be pointers to a tree node and initialize them at the root.
Now move a and b down the tree, trying to use opposite edges at each step, i.e. if a moves down a 0-edge, b moves down a 1-edge unless its not possible.
If a and b reach a leaf, the should point to two numbers with "very few" identical bits.
I just made this algorithm up and do not know if its correct or how to prove it. However it should be in O(n) running time.
Make a recursive function that takes two lists of integers, A and B, as its arguments. As its return value, it returns two integers, one from A and one from B, which maximize the XOR of the two. If all the integers are 0, return (0,0). Otherwise, the function does some processing and calls itself recursively twice, but with smaller integers. In one of the recursive calls, it considers taking an integer from list A to supply a 1 to bit k, and in the other call it considers taking an integer from list B to supply a 1 to bit k.
I don't have time now to fill in the details, but maybe this will be enough for to see the answer? Also, I'm not sure if the run time will be better than N^2, but it probably will be.
We can find the maximum number in O(n) time then loop through the array doing xor with each element. Assuming xor operation cost is O(1) we can find max xor of two numbers in O(n) time.

How to find a 2 unpaired elements in array?

You have an array with n=2k+2 elements where 2 elements haven't pair. Example for 8 elemets array: 1 2 3 47 3 1 2 0. "47" and "0" haven't pair in array. If I have array where only 1 element has't pair, I solve this problem with XOR. But I have 2 unpair elements! What can I do? Solution could be for a O(n) time performance and for O(1) additional memory.
Some hints...
It will take 2 passes. First, go through the list and XOR all elements together. See what you get. Proceed from there.
Edit: The key observation about the result of the first pass should be that it shows you the set of bits in which the 2 unpaired elements differ.
Use INT_MAX/8 bytes of memory. Walk the array. XOR the bit corresponding to each value with 1. If there are 0 or 2 instances the bit will end up 0. If there is only one instance, it will be set. O(1) mem, O(N) time.
Scan the Array and put each number and count in hash.
Rescan and find out the items with count=1.
This is O(n).
You can try this.It will take O(n) time
int xor = arr[0];
int set_bit_no;
int i;
int x = 0; //First unpair number
int y = 0; //second unpair number
for (i = 1; i < n; i++)
xor ^= arr[i];
set_bit_no = xor & ~(xor-1);//Get the rightmost set bit in set_bit_no
for (i = 0; i < n; i++)
{
if (arr[i] & set_bit_no) {
//XOR of first set
x = x ^ arr[i];
}
else
{
//XOR of second set
y = y ^ arr[i];
}
}
Explanation...
arr[] = {2, 4, 7, 9, 2, 4}
1) Get the XOR of all the elements.
xor = 2^4^7^9^2^4 = 14 (1110)
2) Get a number which has only one set bit of the xor.
Since we can easily get the rightmost set bit, let us use it.
set_bit_no = xor & ~(xor-1) = (1110) & ~(1101) = 0010
Now set_bit_no will have only set as rightmost set bit of xor.
3) Now divide the elements in two sets and do xor of
elements in each set, and we get the non-repeating
elements 7 and 9.

Resources