Check whether a point is inside a rectangle by bit operator - algorithm

Days ago, my teacher told me it was possible to check if a given point is inside a given rectangle using only bit operators. Is it true? If so, how can I do that?

This might not answer your question but what you are looking for could be this.
These are the tricks compiled by Sean Eron Anderson and he even put a bounty of $10 for those who can find a single bug. The closest thing I found here is a macro that finds if any integer X has a word which is between M and N
Determine if a word has a byte between m and n
When m < n, this technique tests if a word x contains an unsigned byte value, such that m < value < n. It uses 7 arithmetic/logical operations when n and m are constant.
Note: Bytes that equal n can be reported by likelyhasbetween as false positives, so this should be checked by character if a certain result is needed.
Requirements: x>=0; 0<=m<=127; 0<=n<=128
#define likelyhasbetween(x,m,n) \
((((x)-~0UL/255*(n))&~(x)&((x)&~0UL/255*127)+~0UL/255*(127-(m)))&~0UL/255*128)
This technique would be suitable for a fast pretest. A variation that takes one more operation (8 total for constant m and n) but provides the exact answer is:
#define hasbetween(x,m,n) \
((~0UL/255*(127+(n))-((x)&~0UL/255*127)&~(x)&((x)&~0UL/255*127)+~0UL/255*(127-(m)))&~0UL/255*128)

It is possible if the number is a finite positive integer.
Suppose we have a rectangle represented by the (a1,b1) and (a2,b2). Given a point (x,y), we only need to evaluate the expression (a1<x) & (x<a2) & (b1<y) & (y<b2). So the problems now is to find the corresponding bit operation for the expression c
Let ci be the i-th bit of the number c (which can be obtained by masking ci and bit shift). We prove that for numbers with at most n bit, c<d is equivalent to r_(n-1), where
r_i = ((ci^di) & ((!ci)&di)) | (!(ci^di) & r_(i-1))
Prove: When the ci and di are different, the left expression might be true (depends on ((!ci)&di)), otherwise the right expression might be true (depends on r_(i-1) which is the comparison of next bit).
The expression ((!ci)&di) is actually equivalent to the bit comparison ci < di. Hence, this recursive relation return true that it compares the bit by bit from left to right until we can decide c is smaller than d.
Hence there is an purely bit operation expression corresponding to the comparison operator, and so it is possible to find a point inside a rectangle with pure bitwise operation.
Edit: There is actually no need for condition statement, just expands the r_(n+1), then done.

x,y is in the rectangle {x0<x<x1 and y0<y<y1} if {x0<x and x<x1 and y0<y and y<y1}
If we can simulate < with bit operators, then we're good to go.
What does it mean to say something is < in binary? Consider
a: 0 0 0 0 1 1 0 1
b: 0 0 0 0 1 0 1 1
In the above, a>b, because it contains the first 1 whose counterpart in b is 0. We are those seeking the leftmost bit such that myBit!=otherBit. (== or equiv is a bitwise operator which can be represented with and/or/not)
However we need some way through to propagate information in one bit to many bits. So we ask ourselves this: can we "code" a function using only "bit" operators, which is equivalent to if(q,k,a,b) = if q[k] then a else b. The answer is yes:
We create a bit-word consisting of replicating q[k] onto every bit. There are two ways I can think of to do this:
1) Left-shift by k, then right-shift by wordsize (efficient, but only works if you have shift operators which duplicate the last bit)
2) Inefficient but theoretically correct way:
We left-shift q by k bits
We take this result and and it with 10000...0
We right-shift this by 1 bit, and or it with the non-right-shifted version. This copies the bit in the first place to the second place. We repeat this process until the entire word is the same as the first bit (e.g. 64 times)
Calling this result mask, our function is (mask and a) or (!mask and b): the result will be a if the kth bit of q is true, other the result will be b
Taking the bit-vector c=a!=b and a==1111..1 and b==0000..0, we use our if function to successively test whether the first bit is 1, then the second bit is 1, etc:
a<b :=
if(c,0,
if(a,0, B_LESSTHAN_A, A_LESSTHAN_B),
if(c,1,
if(a,1, B_LESSTHAN_A, A_LESSTHAN_B),
if(c,2,
if(a,2, B_LESSTHAN_A, A_LESSTHAN_B),
if(c,3,
if(a,3, B_LESSTHAN_A, A_LESSTHAN_B),
if(...
if(c,64,
if(a,64, B_LESSTHAN_A, A_LESSTHAN_B),
A_EQUAL_B)
)
...)
)
)
)
)
This takes wordsize steps. It can however be written in 3 lines by using a recursively-defined function, or a fixed-point combinator if recursion is not allowed.
Then we just turn that into an even larger function: xMin<x and x<xMax and yMin<y and y<yMax

Related

Binary problem : how to find integer B conforms to integer A

I want to write an algorithm (in Python), that get all the integers that are conforms to an another integer B, written in binary.
When A is conforms to B, it means that in all positions where B has bits set to 1, A has corresponding bits set to 1.
By example :
If we have 1001, the confoms numbers are : 1111, 1011, 1101;
We can assume that the solution should work with very large numbers (so has to be quite efficient).
I have thought about many solutions about doing some binary operations but I cannot get a complete solution.
Do you have any idea ?
As shown in your example:
An integer with z zero bits has 2**z conforming integers. We can subtract one, because one of these is the integer itself.
Accordingly, your algorithm has to count from 1 to 2**z and replace the z zero bits in the original integer by the z bits of your counter.
In python, you can use bitwise operators to test or change bit positions within an integer.
Examples for bitwise operations:
x & 1 returns 1, if the least-significant bit is set. Otherwise 0
x = x | 4 will set the 3rd bit corresponding to 4
Sketch of your algorithm:
1. Loop through the integer to find and count the zero bits
2. Loop from 1 to 2**z
Inner loop: Scan the z bits of the counter
Transfer the bits to a copy of the original integer
Record/output the resulting conformant integer

Generating a perfect hash function given known list of strings?

Suppose I have a list of N strings, known at compile-time.
I want to generate (at compile-time) a function that will map each string to a distinct integer between 1 and N inclusive. The function should take very little time or space to execute.
For example, suppose my strings are:
{"apple", "orange", "banana"}
Such a function may return:
f("apple") -> 2
f("orange") -> 1
f("banana") -> 3
What's a strategy to generate this function?
I was thinking to analyze the strings at compile time and look for a couple of constants I could mod or add by or something?
The compile-time generation time/space can be quite expensive (but obviously not ridiculously so).
Say you have m distinct strings, and let ai, j be the jth character of the ith string. In the following, I'll assume that they all have the same length. This can be easily translated into any reasonable programming language by treating ai, j as the null character if j ≥ |ai|.
The idea I suggest is composed of two parts:
Find (at most) m - 1 positions differentiating the strings, and store these positions.
Create a perfect hash function by considering the strings as length-m vectors, and storing the parameters of the perfect hash function.
Obviously, in general, the hash function must check at least m - 1 positions. It's easy to see this by induction. For 2 strings, at least 1 character must be checked. Assume it's true for i strings: i - 1 positions must be checked. Create a new set of strings by appending 0 to the end of each of the i strings, and add a new string that is identical to one of the strings, except it has a 1 at the end.
Conversely, it's obvious that it's possible to find at most m - 1 positions sufficient for differentiating the strings (for some sets the number of course might be lower, as low as log to the base of the alphabet size of m). Again, it's easy to see so by induction. Two distinct strings must differ at some position. Placing the strings in a matrix with m rows, there must be some column where not all characters are the same. Partitioning the matrix into two or more parts, and applying the argument recursively to each part with more than 2 rows, shows this.
Say the m - 1 positions are p1, ..., pm - 1. In the following, recall the meaning above for ai, pj for pj ≥ |ai|: it is the null character.
let us define h(ai) = ∑j = 1m - 1[qj ai, pj % n], for random qj and some n. Then h is known to be a universal hash function: the probability of pair-collision P(x ≠ y &wedge; h(x) = h(y)) ≤ 1/n.
Given a universal hash function, there are known constructions for creating a perfect hash function from it. Perhaps the simplest is creating a vector of size m2 and successively trying the above h with n = m2 with randomized coefficients, until there are no collisions. The number of attempts needed until this is achieved, is expected 2 and the probability that more attempts are needed, decreases exponentially.
It is simple. Make a dictionary and assign 1 to the first word, 2 to the second, ... No need to make things complicated, just number your words.
To make the lookup effective, use trie or binary search or whatever tool your language provides.

Maximum xor of a range of numbers

I am grappling with this problem Codeforces 276D. Initially I used a brute force approach which obviously failed for large inputs(It started when inputs were 10000000000 20000000000). In the tutorials Fcdkbear(turtor for the contest) talks about a dp solution where a state is d[p][fl1][fr1][fl2][fr2].
Further in tutorial
We need to know, which bits we can place into binary representation of number а in p-th position. We can place 0 if the following condition is true: p-th bit of L is equal to 0, or p-th bit of L is equal to 1 and variable fl1 shows that current value of a is strictly greater then L. Similarly, we can place 1 if the following condition is true: p-th bit of R is equal to 1, or p-th bit of R is equal to 0 and variable fr1 shows that current value of a is strictly less then R. Similarly, we can obtain, which bits we can place into binary representation of number b in p-th position.
This is going over my head as when ith bit of L is 0 then how come we can place a zero in a's ith bit. If L and R both are in same bucket(2^i'th boundary like 16 and 24) we will eventually place a 0 at 4th whereas we can place a 1 if a = 20 because i-th bit of R is 0 and a > R. I am wondering what is the use of checking if a > L or not.
In essence I do not get the logic of
What states are
How do we recur
I know that might be an overkill but could someone explain it in descriptive manner as editorial is too short to explain anything.
I have already looked in here but suggested solution is different from one given in editorial. Also I know this can be solved with binary search but I am concerned with DP solution only
If I got the problem right: Start to compare the bits of l and r from left (MSB) to right(LSB). As long as these bits are equal there is no freedom of choice, the same bits must appear in a and b. the first bit differing must be 1 in r and 0 in l. they must appear also in a (0) and b(1). from here you can maximise the XOR result. simply use zeros for b an ones for a. that gives a+1==b and the xor result is a+b which is always 2^n-1.
I'm not following the logic as written above but the basic idea is to look bit by bit.
If L and R have different values in the same bit position then we have already found candidates that would maximize the xor'd value of that position (0 xor 1 = 1 xor 0 = 1). The other case to consider is whether the span of R-L is greater than the position value of that bit. If so then there must be two different values of A and B falling between L and R where that bit position has opposite values (as well as being able to generate any combinations of values in the lower bits.)

Algorithm for 0 and any other x

I need to write an algorithm that takes a positive integer x. If integer x is 0, the algorithm returns 0. If it's any other number, the algorithm returns 1.
Here's the catch. I need to condense the algorithm into one equation. i.e. no conditionals. Basically, I need a single equation that equates to 0 if x is zero and 1 if x > 0.
EDIT: As per my comment below. I realize that I wasn't clear enough. I am entering the formula into a system that I don't have control over, hence they strange restrictions.
However, I learned a couple tricks that could be useful in the future!
In C and C++, you can use this trick:
!!x
In those languages, !x evaluates to 1 if x is zero and 0 otherwise. Therefore, !!x evaluates to 1 if x is nonzero and 0 otherwise.
Hope this helps!
Try return (int)(x > 0)
In every programming language I know, (int)(TRUE) == 1 and (int)(FALSE) == 0
Assuming 32-bit integers:
int negX = -x;
return negX >> 31;
Negating x puts a 1 in the highest bit. Shifting right by 31 places moves that 1 to the lowest bit, and fills with 0s. This does nothing to a 0, but converts all positive integers to 1.
This is basically the sign function, but since you specified a positive integer input, you can drop the part that converts negative numbers to -1.
Since virtually every system I know of uses IEEE-754 representation for floating-point numbers, you could just rely on its behavior (namely, that 0.0 / 0.0 is NaN, and NaN != NaN). Pseudo-C (-Java, ...) follows:
float oneOrNAN = (float)(x) / (float)(x);
return oneOrNAN == oneOrNAN;
Like I said, I wasn't clear enough in my problem description. When I said equation, I meant a purely algebraic equation.
I did find an acceptable solution: Y = X/(X - .001)
If it's zero you get 0/ -.001 which is just 0. Any other number, you get 5/4.999 which is close enough to 1 for my particular situation.
However, this is interesting:
!!x
Thanks for the tip!

question about common bit sequences

suppose we have two numbers i want write program which print common bits subsequent which occurs in these number
or
1000010111001010100011110001010010101001011101001001001
0101 01110011011001010111101111111010001001011
one of the answer should be 0101
but constraint is that we should make bitwise operations and mathematical operations
and not string problems ( longest common subsequent)
thanks
common_ones = a & b;
common_zeros = ~a & ~b;
common_sequences = common_ones | common_zeros;
for example:
a 1000010111001010100011110001010010101001011101001001001
b 0000000000010101110011011001010111101111111010001001011
c 0111101000100000101111010111111010111001011000111111101
to clear the single bit sequences you can use this:
c = c & ( c >> 1 );
c = c | ( c << 1 );
c 0111100000000000001111000111111000111000011000111111100
It is not clear if this is what you want, but this is a quick and easy way to find all common bit sequences at the same position in two values. If you are looking for common bit sequences at any position, you would need to rotate one value into each bit position and perform the above tests.
Assuming you have two 32 bit ints a and b. Shift the bits in b by i, and wrap them around (so that the bit that falls out on the right will come in on the left) and xor it with a. Let i go from 0 to 31. This will give you 32 results. If my reasoning is correct, the result with the longest common subsequence should be the one with the most 0s (counting the 0s can be done in a loop for instance). If not, this should at least be a good starting point.
Take a look at the Sequitur-Algorithm.

Resources