Maximum AND of two numbers - algorithm

Given two numbers A and B what can be the maximum number that can be formed by AND operation of any two numbers x and y between A and B it means A ≤ x < y ≤ B.
Example : A=1 and B=3 then answer is 2.
I can't go for brute as both A and B can go upto 10^18

Note: this answer assumes A ≥ 0, which is fair considering the question is not tied to a particular language or integer representation that would give meaning to bit operations on negative integers.
If B is odd, the maximum x & y is B-1, obtained by picking y = B and x = B-1.
If B is even and A is low enough to allow to pick y = B-1 and x = B-2, then the maximum is B-2, for this choice of x and y. Otherwise, there is only one choice, B & (B-1), whatever that evaluate to.

To expand on Pascal Cuoq's excellent answer, if we allow A < 0 and assume two's complement arithmetic (which is what essentially all modern computers use for signed integers), then we again have several cases:
If A < 0 ≤ B, then we may choose x = -1 and y = B, in which case x & y = B.
If A < B < 0, then everything works just like for positive numbers: if B is odd, or if A = B-1, then the optimal choice is x = B-1, y = B; otherwise it is x = B-2, y = B-1.
(The reason it works out exactly the same way is because two's complement signed arithmetic is essentially identical to unsigned binary arithmetic, except that we interpret numbers with their highest bit set as negative. Thus, the only really new case is the one where the range from A to B "wraps around" from -1 to 0.)
Summing up these results, we have that, for A ≤ x < y ≤ B, with any given (possibly signed two's complement) A and B, the maximum of x & y is:
If A < 0 ≤ B, then x = -1 and y = B yield x & y = B.
Otherwise, if B is odd, x = B-1 and y = B yield x & y = B-1.
Otherwise, if B > A+1, then x = B-2 and y = B-1 yield x & y = B-2.
If none of the above hold, the only remaining case is B = A+1 (with B even); in this case, the only possible choice is x = A, y = B; whatever x & y equals in this case, it is trivially the maximum.

Related

Algorithm for selecting the differents pair

May be somebody can help me with it.
So, I have a set of pairs x0-y0, x1-y1, etc.
And always x[i]<y[i]. Thus I need a function (or algorithm) for every pair, so
F(x[i],y[i]) = result[i], and each result for a particular pair must be an integer unique value.
Let M = max(y) - min(y) + 1, then use the formula:
F(x, y) = x * M + y
Remarks:
You don't have to use the exact maximum and minimum, you can use an upperbound and a lowerbound, M = U - L + 1 with U larger than all y and L smaller than all y;
Of course you could do it the other way around instead, with K = max(x) - min(x) + 1, and F(x, y) = y * K + x;
When using a finite integer type, be careful with overflow, for instance if x and y both have values larger than 46340, then F(x, y) won't fit in a 32-bit signed integer.

Finding distinct pairs {x, y} that satisfies the equation 1/x + 1/y = 1/n with x, y, and n being whole numbers

The task is to find the amount of distinct pairs of {x, y} that fits the equation 1/x + 1/y = 1/n, with n being the input given by the user. Different ordering of x and y does not count as a new pair.
For example, the value n = 2 will mean 1/n = 1/2. 1/2 can be formed with two pairs of {x, y}, whcih are 6 and 3 and 4 and 4.
The value n = 3 will mean 1/n = 1/3. 1/3 can be formed with two pairs of {x, y}, which are 4 and 12 and 6 and 6.
The mathematical equation of 1/x + 1/y = 1/n can be converted to y = nx/(x-n) where if y and x in said converted equation are whole, they count as a pair of {x, y}. Using said converted formula, I will iterate n times starting from x = n + 1 and adding x by 1 per iteration to find whether nx % (x - n) == 0; if it yields true, the x and y are a new distinct pair.
I found the answer to limit my iteration by n times by manually computing the answers and finding the number of repetitions 'pattern'. x also starts with n+1 because otherwise, division by zero will happen or y will result in a negative number. The modulo operator is to indicate that the y attained is whole.
Questions:
Is there a mathematical explanation behind why the iteration is limited to n times? I found out that the limit of iteration is n times by doing manual computation and finding the pattern: that I only need to iterate n times to find the amount of distinct pairs.
Is there another way to find the amount of distinct pairs {x, y} other than my method above, which is by finding the VALUES of distinct pairs itself and then summing the amount of distinct pair? Is there a quick mathematical formula I'm not aware of?
For reference, my code can be seen here: https://gist.github.com/TakeNoteIAmHere/596eaa2ccf5815fe9bbc20172dce7a63
Assuming that x,y,n > 0 we have
Observation 1: both, x and y must be greater than n
Observation 2: since (x,y) and (y,x) do not count as distinct, we can assume that x <= y.
Observation 3: x = y = 2n is always a solution and if x > 2n then y < x (thus no new solution)
This means the possible values for x are from n+1 up to 2n.
A little algebra convers the equation
1/x + 1/y = n
into
(x-n)*(y-n) = n*n
Since we want a solution in integers, we seek integers f, g so that
f*g = n*n
and then the solution for x and y is
x = f+n, y = g+n
I think the easiest way to proceed is to factorise n, ie write
n = (P[1]^k[1]) * .. *(P[m]^k[m])
where the Ps are distinct primes, the ks positive integers and ^ denotes exponentiation.
Then the possibilities for f and g are
f = P[1]^a[1]) * .. *(P[m]^a[m])
g = P[1]^b[1]) * .. *(P[m]^b[m])
where the as and bs satisfy, for each i=1..m
0<=a[i]<=2*k[i]
b[i] = 2*k[i] - a[i]
If we just wanted to count the number of solutions, we would just need to count the number of fs, ie the number of distinct sequences a[]. But this is just
Nall = (2*k[1]+1)*... (2*[k[m]+1)
However we want to count the solution (f,g) and (g,f) as being the same. There is only one case where f = g (because the factorisation into primes is unique, we can only have f=g if the a[] equal the b[]) and so the number we seek is
1 + (Nall-1)/2

Find the closest to a given natural number, which satisfies non-linear condition

I have three integers: A, B, C i need to find integer X, which is closest to C. If N is any natural number, then A, B and X should satisfy the following equation:
A*B*X=sqrt(N)
Could you help with algorithm?
we can do a binary search over all possible values of N, and compare corresponding value of X = sqrt(N)/(A*B)) to decide which half to carry on search.
A possible implementation in python could be -
A = 5
B = 2
C = 3
left = -10000000000000
right = 10000000000000 #assuming that's the maximum value N can take
while right-left>1:
N = (left+right)//2
X = N**.5/(A*B)
if X>C:
right = N
else:
left = N
N = (left+right)//2
print(N)
which in this case outputs: 900

Recursive division algorithm for two n bit numbers

In the below division algorithm, I am not able to understand why multiplying q and r by two works and also why r is incremented if x is odd.
Please give a theoretical justification of this recursive division algorithm.
Thanks in advance.
function divide(x, y)
if x = 0:
return (q, r) = (0, 0)
(q, r) = divide(floor(x/2), y)
q = 2q, r = 2r
if x is odd:
r = r + 1
if r ≥ y:
r = r − y, q = q + 1
return (q, r)
Let's assume you want to divide x by y, i.e. represent x = Q * y + R
Let's assume that x is even. You recursively divide x / 2 by y and get your desired representation for a smaller case: x / 2 = q * y + r.
By multiplying it by two, you would get: x = 2q * y + 2r. Looking at the representation you wanted to get for x in the first place, you see that you have found it! Let Q = 2q and R = 2r and you found the desired Q and R.
If x is odd, you again first get the desired representation for a smaller case: (x - 1) / 2 = q * y + r, multiply it by two: x - 1 = 2q * y + 2r, and send 1 to the right: x = 2q * y + 2r + 1. Again, you have found Q and R you wanted: Q = 2q, R = 2r + 1.
The final part of the algorithm is just normalization so that r < y. r can become bigger than y when you perform multiplication by two.
Algorithm PuzzleSolve(k,S,U) :
Input: An integer k, sequence S, and set U
Output: An enumeration of all k-length extensions to S using elements in U without repetitions
for each e in U do
Add e to the end of S
Remove e from U /e is now being used/
if k == 1 then
Test whether S is a configuration that solves the puzzle
if S solves the puzzle then
return "Solution found: " S
else
PuzzleSolve(k-1,S,U) /a recursive call/
Remove e from the end of S
Add e back to U e is now considered as unused
This algorithm enumerates every possible size-k ordered subset of U, and tests each subset for being
a possible solution to our puzzle. For summation puzzles, U = 0,1,2,3,4,5,6,7,8,9 and each position
in the sequence corresponds to a given letter. For example, the first position could stand for b, the
second for o, the third for y, and so on.

How to prove the correctness of the algorithm for "Arrange given numbers to form the biggest number"?

Arrange given numbers to form the biggest number gives the algorithm.
It uses the following text to prove the correctness of the algorithm:
So how do we go about it? The idea is to use any comparison based sorting algorithm. In the used sorting algorithm, instead of using the default comparison, write a comparison function myCompare() and use it to sort numbers. Given two numbers X and Y, how should myCompare() decide which number to put first – we compare two numbers XY (Y appended at the end of X) and YX (X appended at the end of Y). If XY is larger, then X should come before Y in output, else Y should come before. For example, let X and Y be 542 and 60. To compare X and Y, we compare 54260 and 60542. Since 60542 is greater than 54260, we put Y first.
Consider three numers: X, Y and Z. Use X -> Y to indicate that X should come before Y. A comparison based algorithm can use the following two comparisons to sort X, Y and Z into XYZ: XY >= YX => X -> Y and YZ >= ZY => Y -> Z. But these two comparisons do not necessarily ensure that XYZ is the largest number. In other words, the fact that X should come before Y and Y should come before Z does not necessarily ensure that XYZ form the largest number. Take YZX as an example. To prove XYZ >= YZX, we need to prove that X(YZ) >= (YZ)X which meains that X should before YZ as a whole to form a bigger number.
Can anyone give a formal proof of the correctness of the algorithm?
First we will prove that if X "<" Y and Y "<" Z then X "<" Z. Assuming that they have p, q and r digits respectively, the first two relations reduce to
X * 10^q + Y ≥ Y * 10^p + X ⇒ X * (10^q - 1) ≥ Y * (10^p - 1)
Y * 10^r + Z ≥ Z * 10^q + Y ⇒ Y * (10^r - 1) ≥ Z * (10^q - 1)
We want to prove
X * 10^r + Z ≥ Z * 10^p + X which is equivalent to X * (10^r - 1) ≥ Z * (10^p - 1)
But this can be proved simply by multiplying the first two inequalities and cancelling off common terms.
Now that we have shown that the relation is transitive (and thus can be used to define a sort order), it is easy to show that it works to solve the problem.
Suppose the numbers given are A, B, C … such that A "<" B "<" C "<" D…. We will show that A has to come first in the final number. If not, we have a string like (some prefix)XA(some suffix) as the final number. Easily, (some prefix)AX(some suffix) is a larger number because A "<" X for all X due to transitivity. Continuing in this fashion A bubbles to the left till it becomes the first element.
Now that we have fixed the first element, the same argument can be applied to B and so on to show that the best solution is ABCD…

Resources