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

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…

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

How to find number of steps to transform (a,b) to (x,y)

Given 2 numbers a=1 and b=1.
At each steps, you can do one of the following:
a+=b;
b+=a;
If it's possible to transform a into x and b into y, find the minimum steps needed
x and y can be arbitrarily large (more than 10^15)
My approach so far was just to do a recursive backtrack which will be around O(2^min(x,y)) in complexity (too large). DP won't do either since the states can be more than 10^15.
Any idea? Is there any number theory that is needed to solve this?
P.s. This is not a homework.
Given that you reached some (x,y) the only way to get there is if you added the smaller value into what is now the larger value. Say x > y, then the only possible previous state is x-y, y.
Also note that the number of steps to get to x,y is the same to get to y,x.
So the solution you are looking for is something like
steps(x,y):
if x < y: return steps(y, x)
if y == 1: return x - 1
if y == 0: throw error # You can't get this combination.
return x / y + steps (y, x % y)
In other words, find the depth of a node in the Calkin--Wilf tree. The node exists iff gcd(a, b) = 1. You can modify the gcd algorithm to give the number of operations as a byproduct (sum all of the quotients computed along the way and subtract one).

exponential multiplication algorithm that runs in O(n) time?

I am reading an algorithms textbook and I am stumped by this question:
Suppose we want to compute the value x^y, where x and y are positive
integers with m and n bits, respectively. One way to solve the problem is to perform y - 1 multiplications by x. Can you give a more efficient algorithm that uses only O(n) multiplication steps?
Would this be a divide and conquer algorithm? y-1 multiplications by x would run in theta(n) right? .. I don't know where to start with this question
I understand this better in an iterative way:
You can compute x^z for all powers of two: z = (2^0, 2^1, 2^2, ... ,2^(n-1))
Simply by going from 1 to n and applying x^(2^(i+1)) = x^(2^i) * x^(2^i).
Now you can use these n values to compute x^y:
result = 1
for i=0 to n-1:
if the i'th bit in y is on:
result *= x^(2^i)
return result
All is done in O(n)
Apply a simple recursion for divide and conquer.
Here i am posting a more like a pseudo code.
x^y :=
base case: if y==1 return x;
if y%2==0:
then (x^2)^(y/2;
else
x.(x^2)^((y-1)/2);
The y-1 multiplications solution is based on the identity x^y = x * x^(y-1). By repeated application of the identity, you know that you will decrease y down to 1 in y-1 steps.
A better idea is to decrease y more "energically". Assuming an even y, we have x^y = x^(2*y/2) = (x^2)^(y/2). Assuming an odd y, we have x^y = x^(2*y/2+1) = x * (x^2)^(y/2).
You see that you can halve y, provided you continue the power computation with x^2 instead of x.
Recursively:
Power(x, y)=
1 if y = 0
x if y = 1
Power(x * x, y / 2) if y even
x * Power(x * x, y / 2) if y odd
Another way to view it is to read y as a sum of weighted bits. y = b0 + 2.b1 + 4.b2 + 8.b3...
The properties of exponentiation imply:
x^y = x^b0 . x^(2.b1) . x^(4.b2) . x^(8.b2)...
= x^b0 . (x^2)^b1 . (x^4)^b2 . (x^8)^b3...
You can obtain the desired powers of x by squaring, and the binary decomposition of y tells you which powers to multiply.

Compute the number of binary trees with i nodes

Let bi be the number of binary trees with i nodes. Compute b10.
This is a problem I've come upon.
I've able to come up with these so far:
B0=1
B1=1
B2=2
B3=5
B4=12
It quickly gets a bit too much as I gets bigger.
Can anyone think of a better way to compute Bi than just drawing out the trees and count them?
I typed your answer into OEIS and it came up with a few results.
A promising result is A000669 - the number of series-reduced planted trees with n leaves. The following example is provided: a(4)=5 with the following series-reduced planted trees: (oooo), (oo(oo)), (o(ooo)), (o(o(oo))), ((oo)(oo)). That said, our trees are not necessarily planted.
However, after a bit of work, I must inform you that your value for B4 is incorrect - the correct answer is 14. Then the answer is clear: the Catalan numbers. The Catalan numbers count a strange and varied number of things, including the problem you're presented here (via Wolfram). It is worth noting Catalan number identity (8) here - the recurrence that defines the Catalan numbers. This summation can be thought of as deciding the number of nodes that will be to the left of a node (and the rest will be to the right).
An easier way to conceptualize this is using Dyck words. let X mean 'left parenthesis' and Y mean '0'. (I am using a list representation for trees - nodes to the left are lists on the left of an element and visa versa; if a node has no left or right lists it is considered a leaf.) We will put in right parentheses where appropriate. Then our trees for B3 are as follows:
(((0)0)0) => X X X Y Y Y
((0)0(0)) => X X Y Y X Y
(0(0(0))) => X Y X Y X Y
((0(0))0) => X X Y X Y Y
(0((0)0)) => X Y X X Y Y
From Wikipedia, the five 2n-length Dyck words of this form are XXXYYY, XYXXYY, XYXYXY, XXYYXY, and XXYXYY. And finally, the closed form
Bn = (1 / (n + 1)) * (2n choose n) = (2n!)/((n+1)!(n!))

Resources