I have a set of integers (x, y, z) and a function that takes 3 integers (u, v, w). How can I test if (x,y,z) == (u,v,w)? The naive way is:
bool match = (x == u || x == v || x == w) && (y == u || y == v || y == w) && (z == u || z == v || z == w);
Does anyone know of some smart bit operations/arithmetic to do the same thing?
Edit: I can assume that neither (x, y, z) or (u, v, w) contain duplicates.
In this case, you can replace the logical operations by bitwise operations to eliminate the branching:
bool match = (x == u | x == v | x == w)
& (y == u | y == v | y == w)
& (z == u | z == v | z == w);
However, you would have to measure the performance effect to see if this is faster or slower.
You can eliminate a bunch of unequal vectors up front by converting to unsigned and comparing the sums before doing the real test.
If a and b are the same then a^b is zero. So !(a^b) is non-zero only when a and b are the same. Supposing your platform can do logical 'not' without a branch, you can therefore test whether a is a member of (u, v, w) with a single branch using:
if(!(a^u) | !(a^v) | !(a^w))
And hence whether all of (x, y, z) are members of (u, v, w) using:
if(
(!(a^u) | !(a^v) | !(a^w))) &
(!(b^u) | !(b^v) | !(b^w))) &
(!(c^u) | !(c^v) | !(c^w))))
i.e. just doing a bitwise and on the various results, and again only a single branch.
If your platform needs a branch to perform !, e.g. if it's performed essentially as a ? 0 : -1, then that's ten conditionals and no better than the naive solution.
In C there is no way to do this without branching.
If you are willing to inline-assembly you can do this with some CMPXCHG instructions.
As pointed out in the comments, your 'naive' way matches whenever all the elements in (x,y,z) are contained in the set (u,v,w). If you really want to test if the sets are equivalent, you probably want
(x==u && ((y==v && z==w) || (y==w && z==v))) ||
(y==u && ((z==v && x==w) || (x==w && z==v))) ||
(z==u && ((x==v && y==w) || (y==w && x==v)));
You can quickly filter out many mismatches with
bad = (x+y+z) - (u+v+w);
Some processors have a non-branching 'min' and 'max' instructions, which would allow you to do
a = min(x,y)
b = max(x,y)
c = min(b,z)
x = min(a,c)
y = max(a,c)
z = max(b,z)
//repeat sorting sequence for u,v,w
match = (x==u)&(y==v)&(z==w);
Related
I have 3 corners of an axis aligned box, I must find the 4th corner.
How can I compute it more efficiently:
if (loc[0].first != loc[1].first && loc[0].first != loc[2].first)
x = loc[0].first;
else if (loc[1].first != loc[0].first && loc[1].first != loc[2].first)
x = loc[1].first;
else
x = loc[2].first;
if (loc[0].second != loc[1].second && loc[0].second != loc[2].second)
y = loc[0].second;
else if (loc[1].second != loc[0].second && loc[1].second!=loc[2].second)
y = loc[1].second;
else
y = loc[2].second;
Assuming you have 2 identical (integral) numbers and a third one, xor might give you the expected one:
x = loc[0].first ^ loc[1].first ^ loc[2].first;
y = loc[0].second ^ loc[1].second ^ loc[2].second;
if type is not integral (so no xor), it seems more readable to check for equality (that also does one check for equality instead of 2 checks for inequality by test):
if (loc[0].first == loc[1].first)
x = loc[2].first;
else if (loc[0].first == loc[2].first)
x = loc[1].first;
else // loc[1].first == loc[2].first
x = loc[0].first;
If the points are guaranteed to be perfectly aligned vertically or horizontally, the fourth corner is found at the unique abscissa and unique ordinate.
if X0 == X1:
X3= X2
elif X0 == X2:
X3= X1
else:
X3= X0
You can't do this in less than two comparisons, because the outcome depends on the three values.
Same code on Y, independently. Or, you can even spare a comparison on Y, because if two X's are known to be equal, the corresponding Y's are perforce different. Hence on average a total of 8/3 comparisons.
If you are after the ordered axis-aligned bounding box, take the minimum and maximum of the abscissas and ordinates separately.
I'm exercising opreators in C++ and I don't understand the output of the code bellow
int x = 21, z = 33, y = 43;
cout << (!(z < y&& x < z) || !(x = z - y)) << endl;
I wrote it with the thought to be true and I understand it as "it's not the case z is less than y and x is less than z (which is false) or it's not the case x is equal to the difference of z and y (which is true)" so I expected output 1 (=true) and I'm confused that's not the case. Can you explain me where I'm making a mistake?
edit: Thanks for the answers, it's funny how I made such trivial mistakes I actually read about.
The part that you misinterpreted:
!(x = z - y))
x = z - y is assignment. It yields -10 as result. -10 is not 0, hence negating it yields false.
Now, first part of the expression:
!(z < y&& x < z)
!(33 < 43 && 21 < 33)
!(true && true)
!(true)
false
Putting it together:
(false || false) == false
This = is an assignment operator. It assigns values.
This == is a comparison operator. It is used to compare two values.
int value = 5, value2 = 12;
if(value == value2)
{
// do something if value and value2 are EQUAL (which they are not)
}
See this link for more information on operators in C++.
A r*c grid has only 0's ans 1's . In each iteration , if there is any adjacent cell (up,down,left,right) same to it, the value of the current cell will be flipped . Now , how to come up with a bitwise formula to do this . It can be done with a simple if condition , but I want to know the bitwise operation to do this so the whole operation can be done once per row .
I am talking about this problem . I saw a solution using this concept here . But I couldn't understand how this is used to do the determine the cell value by this XOR operations.
ans[i] ^= ((l ^ r) | (r ^ u) | (u ^ d)) | (~s[i] ^ l);
ans[i] &= prefix;
Any help would be appreciated :D
For the start, consider s[i], l, r, u, and d to be single bits, that is, boolean variables.
s[i] (abbreviated as s in this answer) is the old color of the cell to be updated.
l, r, u, and d are the colors of the adjacent cells left, right, above (up), and below (down) of the cell to be updated.
ans[i] (abbreviated as ans in this answer) is the new color of the cell after the update.
We initialize ans = s and update it only if needed.
Recall the rules from the game for a single cell C:
If all cells adjacent to C have the opposite color of C, then C retains its color.
Otherwise (if a cell adjacent to C has the same color as C), C changes its color.
Are there various adjacent colors?
For the first condition you can use a fail-fast approach. No matter the color of C, if the adjacent cells have various colors (some are 0 and some are 1) then C changes its color. To check whether the adjacent cells l, r, u, and d have various colors you only need three checks ✱:
various_adjacent_colors = (l != r) || (r != u) || (u != d)
In bit-wise notation this is
various_adjacent_colors = (l ^ r) | (r ^ u) | (u ^ d)
✱ The "missing" checks like r != d are not necessary. Think about it the other way: If all three checks fail, then we know (l == r) && (r == u) && (u == d). In that case, from transitivity of == follows that (l == u), and (l == d), and (r == d). Therefore, all colors are the same.
Fail-Fast for various adjacent colors
If we find various adjacent colors, then we change s:
if (various_adjacent_colors)
ans = !s
In bit-wise notation this is
ans ^= various_adjacent_colors
Are all colors equal?
If we did not fail-fast, we know that all adjacent colors are equal to each other but not if they are equal to s. If s == all_adjacent_colors then we change s and if s != all_adjacent_colors then we retain s.
if (!various_adjacent_colors && s == l) // l can be replaced by either r, u, or d
ans = !s
In bit-wise notation this is
ans ^= ~various_adjacent_colors & ~(s ^ l) or
ans ^= ~various_adjacent_colors & (~s ^ l)
Putting everything together
Now let's inline (and slightly simplify) all the bit-wise notations:
vari = (l ^ r) | (r ^ u) | (u ^ d); ans ^= vari; ans ^= ~vari & (~s ^ l) is the same as
vari = (l ^ r) | (r ^ u) | (u ^ d); ans ^= vari | (~s ^ l) is the same as
ans ^= ((l ^ r) | (r ^ u) | (u ^ d)) | (~s ^ l)
Seems familiar, right? :)
From single bits to bit-vectors
So far, we only considered single bits. The linked solution uses bit-vectors instead to simultaneously update all bits/cells in a row of the 2D game board. This approach only fails at the borders of the game board:
From r = s[i] << 1 the game board might end up bigger than it should be. ans[i] &= prefix fixes the size by masking overhanging bits.
At the top and bottom row the update does not work because u = s[i-1] and d = s[i+i] do not exist. The author updates these rows "manually" in a for loop.
The update for the leftmost and rightmost cell in each row might be wrong since r = s[i] << 1 and l = s[i] >> 1 shift in "adjacent" cells of color 0 which are not actually in the game. The author updates these cells "manually" in another for loop.
By the way: A (better?) alternative to the mentioned "manual" border updates is to slightly enlarge the game board with an additional virtual row/column at each border. Before each game iteration, the virtual rows/columns are initialized such that they don't affect the update. Then the update of the actual game board is done as usual. The virtual rows/columns don't have to be stored, instead use ...
// define once for the game
bitset<N> maskMsb, maskLsb;
maskMsb[m-1] = 1;
maskLsb[0] = 1;
// define for each row when updating the game board
bitset<N> l = (s[i] >> 1) | (~s[i] & maskMsb);
bitset<N> r = (s[i] << 1) | (~s[i] & maskLsb);
bitset<N> u = i+1 <= n-1 ? s[i+1] : ~s[n-1];
bitset<N> d = i-1 >= 0 ? s[i-1] : ~s[0];
Before reading this question please consider that it is intended for use with the Z3 solver tool and it's c++ api (everything is redefined so it's not normal c++ syntax)
Can someone explain how do I mix boolean logic with integers (programing wise)?
Example:
y = (x > 10 and x < 100) //y hsould be true or false (boolean)
z = (y == true and k > 20 and k < 200)
m = (z or w) //suppose w takes true of false (boolean)
I tried with the examples given in the c++ file but I can't figure out how it works when mixing integer arithmetic and boolean.
Writing answer assuming you a beginner of c++.
May be you are looking for this.
bool y,z,m,w;
int x, k;
y = (x>10 && x<100);
z = (y == true && k > 20 && k < 200);
m = (z || w);
Let see what this line means:
y = (x>10 && x<100);
here if x is greater than 10 x>10 results true. In the same way if x is less than 100 x<100 results true. if both of them are true, the right side results true, which will be assigned to y.
|| means or.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I've got something like these in one of my functions and it returns false.
if ((X = ax && Y == ay) || (X == bx && Y == ay) || (X == cx && Y == ay) || (X == ax && Y == by) || (X == cx && Y == by) || (X == ax && Y == cy) || (X == bx && Y == cy) || (X == cx && Y == cy))
return true;
else
return false;
However if I call the function with the same parameters, but changed code to only this, it returns true.
if (X == bx && Y == ay)
return true;
else
return false;
Why is this happening? The condition in second code is one of the conditions in first code, so If one of them is true it should return true, am I right? I expect the first condition to return true
That "=" right near the beginning of the long condition needs to be a "=="! You're assigning a new value to X rather than just testing it, which is causing all the other tests to fail.
= is an assignment operator, it is a common mistake to accidentally use it for comparison, which is also your case. In the first part of your condition: (X = ax && Y == ay) you change the value of X by assigning ax to it, which then affects the result of the rest of the condition.
Also note that:
if (A || B || C || D)
return true;
else
return false;
is equal to:
return (A || B || C || D);
if((X = ax && Y == ay) || //Problem is here
You need to make it
if((X == ax && Y == ay) ||
Your code is failing for X = bx and Y = ay as in the first case, the value ax gets assigned to X, which is TRUE, but Y is not ay which makes the first comparison false. All comparisons after that evaluate to false which causes the first test to fail.