Minimum number of steps required to convert A to B - algorithm

I have recently participated in a coding contest where one of the problems was as follows:
Given two integers X and Y, find the minimum number of steps required to convert X to Y. You can perform the following operations any number of times in any order:
1) Divide X by any integer A, 2)Multiply X by any integer B.
Example: If X=15 and Y=10, then first multiply X by 2 which gives 30 and then divide 30 by 3 to get Y(i.e.,10). So the minimum no. of steps in this case is 2.
I have no idea how to solve it.

As stated, the minimum number of steps is no greater than two: you can always choose A=X and B=Y so that X/A*B = X/X*Y = Y.
The only times you can do better than this are the following:
if X % Y = 0, the minimum number of steps is 1 and the correct choice is A=(X/Y).
if Y % X = 0, the minimum number of steps is 1 and the correct choice is B=(Y/X).
if X = Y, the minimum number of steps is 0 as no multiplications or divisions are required at all.

Related

How does subsets of subsets iteration work?

I read
for ( x = y; x > 0; x = ( y & (x-1) ) )
generates all subsets of bitmask y.
How does this iteration work? Any intuitive explanation?
source: http://codeforces.com/blog/entry/45223
see suboptimal solution section.
Intuition: Taken as a number, the bitmask y cannot have more than y subsets. So, by counting down x, you are guaranteed to hit every subset of y by bitmasking. But this creates a lot of duplicates. Think about 1101. If you count down from that and mask with y, the sequence will go. 1101, 1100, 1001, 1000, 1001, 1000, and so on. By assigning x the result of the masking operation, you skip to its last occurrence.
Proof: This leads to a simple proof by induction. Clearly, for bit strings of length 1, this procedure works. The only two subsets, 1, and 0, are emitted in that order.
Now suppose this procedure works for bitstrings of length N. Suppose Z is a bitstring of length N. If you create the bitstring 0Z, then you follow the same sequence as for Z along, since subtraction does not ever turn on higher order bits. If you create the bitstring 1Z, then the following happens: For the first 2^nnz(Z) steps, the original Z sequence is followed, with 1 prepended. And for the last 2^nnz(Z) steps, the original Z sequence is followed, with 0 prepended. Since the procedure visits every element of the smaller sequence twice, prepending 1 the first time, and 0 the second, we conclude that the procedure emits every subset of 1Z.
Taken together, we see that the procedure works for all bit strings.
The first simple fact that is used here is that if we, say, take value 7 (111 in binary) and start decrementing it repeatedly (all the way to 0) we'll pass through binary representations
111, 110, 101, 100, 011, 010, 001, 000
which in a rather obvious way to represent all possible subsets of an original 3-set.
The second fact is that in binary "to decrement x" ("to subtract 1 from x") means: to invert all bits of x starting from the least significant (rightmost) one and to the left up to (and including) the first 1 in the representation of x. "To the left" here means "in direction of increasing bit significance".
E.g.
00001000 - 1 = 00000111, i.e. we invert the `1000` tail
01010101 - 1 = 01010100, i.e. we invert just the `1` tail
10000000 - 1 = 01111111, i.e. we invert the whole thing
and so on
The decrement operation "turns off" the least significant 1 bit in the binary representation and "turns on" all zero bits to the right of it.
Now, the third fact is that in your case 1 bits of x are always a subset of 1 bits of y, since we begin with x = y and do x = (whatever) & y on every iteration.
When we do x - 1 we "turn off" (set to 0) the lowest 1 in x and "turn on" (set to 1) all 0 in x to the right from that lowest 1.
When we follow that with & y in x = (x - 1) & y we "turn off" some original bit of y in x and "turn on" all lower original bits of y in x.
At this point it should already be fairly obvious that this operation is simply a "masked decrement" of x: by doing x = (x - 1) & y we simply decrement the value of x under assumption that only bits masked by y form the value of x, while all other bits are just negligible "padding bits".
To draw the parallel to the above example with decrementing 7, the initial value of y might look as 10010100. Operation x = (x - 1) & y will see this value as a "distributed 7" of sorts (speaking informally). The x will proceed through the following values
1..1.1.., 1..1.0.., 1..0.1.., 1..0.0.., 0..1.1.., 0..1.0.., 0..0.1.., 0..0.0..
where . designates the "pading"bits" of x, which do not really participate in this "masked decrement" operation (in reality they will be 0). Note the similarity with the original example with 7.

How to solve SPOJ : SCALE using binary search?

http://www.spoj.com/problems/SCALE/
I am trying to do it using recursion but getting TLE.
The tags of the problem say BINARY SEARCH.
How can one do it using binary search ?
Thanx in advance.
First thing to notice here is that if you had two weights of each size instead of one, then the problem would be quite trivial, as we we would only need to represent X in its base 3 representation and take corresponding number of weights. For, example if X=21 then we could take two times P_3 and one time P_2, and put those into another scale.
Now let's try to make something similar using the fact that we can add to both scales (including the one where X is placed):
Assume that X <= P_1+P_2+...+P_n, that would mean that X <= P_n + (P_n-1)/2 (easy to understand why). Therefore, X + P_(n-1) + P_(n-2)+...+P_1 < 2*P_n.
(*) What that means is that if we add some of the weights from 1 to n-1 to same scale as X, then the number on that scale still does
not have 2 in its n-th rightmost digit (either 0 or 1).
From now on assume that digit means a digit of a number in its base-3 representation (but it can temporarily become larger than 2 :P ). Now lets denote the total weight of first scale (where X is placed) as A=X and the other scale is B=0 and our goal is to make them equal (both A and B will change as we will make our progress) .
Let's iterate through all digits of the A from smallest to largest (leftmost). If the current digit index is i and it:
Equals to 0 then just ignore and proceed further
Equals to 1 then we place weight P_i=3^(i-1) on scale B.
Equals to 2 then we add P_i=3^(i-1) to scale A. Note that it would result in the increase of the digit (i+1).
Equals to 3 (yes this case is possible, if both current and previous digit were 2) add 1 to digit at index i+1 and go further (no weights are added to any scale).
Due to (*) obviously the procedure will run correctly (as the last digit will be equal to 1 in A), as we will choose only one weight from the set and place them correctly, and obviously the numbers A and B will be equal after the procedure is complete.
Now second case X > P_1+P_2+...+P_n. Obviously we cannot balance even if we place all weights on the second scale.
This completes the proof and shows when it is possible and the way how to place the weights to both scales to equalise them.
EDIT:
C++ code which I successfully submitted on SPOJ just now https://ideone.com/tbB7Ve
The solution to this problem is quite trivial. The idea is the same as #Yerken's answer, but expressed in a bit different way:
Only the first weight has a mass not divisible by 3. So the first weight is the only one has effect on balancing mod 3 property of the 2 scales:
If X mod 3 == 0, the first weight must not be used
If X mod 3 == 1, the first weight must be on scale B (the currently empty one)
If X mod 3 == 2, the first weight must be on scale A
Subtract both scales by weight(B) --> solution doesn't change, and now weight(A) is divisible by 3 while weight(B) == 0
Set X' = weight(A)/3 and divide every weights Pi by 3 ==> Solution doesn't change, and now it's the same problem with N' = N-1 and X' = (X+1)/3
pseudo-code:
listA <- empty
listB <- empty
for i = 1 to N {
if (X == 0) break for loop; // done!
if (X mod 3 == 1) then push i to listB;
if (X mod 3 == 2) then push i to listA;
X = (X + 1)/3; // integer division
}
hasSolution <- (X == 0)
C++ code: http://ideone.com/LXLGmE

algorithm to find a number in which product of number of 4 & 7 is maximum in given range

I am stuck in a question in which lower bound L and Upper bound U is given.
Now suppose in the decimal representation of integer X digit 4 appears A times and digit 7 appears B times.
Problem is to find X which has maximum value of A*B for L<=X<=U.
Is there any efficient algorithm to solve it?
If I understood the problem correctly, the following should work:
Assume all numbers have the same number of digits (if e.g. L has less digits than U, we can just fill in the beginning with 0 s).
Let Z = U - L.
Now we go from the first (/highest/leftmost) digit to the last one. If we are looking at the i th digit, let L(i), U(i), Z(i) and X(i) be the corresponding digit.
for all leading Z(i) which are 0, we set X(i) = L(i) (we don't have a choice).
For the first not 0 Z(i) check: is there a 4 or a 7 in the interval [L(i), U(i)-1]? If yes let X(i) be that 4 or 7 otherwise let X(i) = U(i)-1.
Now fill up the rest of X with 4s and 7s such that you choose a 4 if you have assigned more 7s so far and vice versa.
Maybe an example can help in understanding this:
Given U = 5000 and L = 4900.
Now Z = 0100.
From the algorithm we set
X(1) = L(1) = 4 (we have no choice)
X(2) = U(2)-1 = 9 (the first non 0 digit in Z)
X(3) = 7 (we already had a 4)
X(4) = 4 (can be chosen arbitrarily)
Leading to X = 4974 with an objective of 2*1=2
It seems you have the algorithm thought out already.
Just break it down piece by piece and solve each part. I usually write something like you did there with comments and then break those down until they are at a reasonable bite size to write code for.
When you have it working, if needed, you can optimize it.

quiz about bit related topics

i have following quiz:
Let x be an integer larger than the odd number q. Change the value of x using the following rule
if x is even
then x / 2
else x – q
until x becomes smaller than q
If the final value of x is zero, what can you say about the original input value?
I am thinking about one thing: if x is odd or x=2*k+1 and we are subtract also odd number, we get even. Also I want to note, that unless x is power of 2, at some step dividing by 2, we get odd number. Let take q=11; x>11;let's take x=23; because x=23 is odd, we will have x=x-q x=23-11=12; now x is even so we will have x/2=6<11, so here we can't determine which value of x is about,but if x=22, then we will have x=x/2=11 x=11 is odd, so we will have x-q=0--> it means that x is multiple of q, but which one odd or even number? Let's take x=33; x is odd so x=x-11=22 it is even x=x/2=11, it is odd so x-q=0; no does it means that x is multiple of q?
Yes, it is apparently that x is multiple of q.

Number of ways to add up to a sum S with N numbers

Say S = 5 and N = 3 the solutions would look like - <0,0,5> <0,1,4> <0,2,3> <0,3,2> <5,0,0> <2,3,0> <3,2,0> <1,2,2> etc etc.
In the general case, N nested loops can be used to solve the problem. Run N nested loop, inside them check if the loop variables add upto S.
If we do not know N ahead of time, we can use a recursive solution. In each level, run a loop starting from 0 to N, and then call the function itself again. When we reach a depth of N, see if the numbers obtained add up to S.
Any other dynamic programming solution?
Try this recursive function:
f(s, n) = 1 if s = 0
= 0 if s != 0 and n = 0
= sum f(s - i, n - 1) over i in [0, s] otherwise
To use dynamic programming you can cache the value of f after evaluating it, and check if the value already exists in the cache before evaluating it.
There is a closed form formula : binomial(s + n - 1, s) or binomial(s+n-1,n-1)
Those numbers are the simplex numbers.
If you want to compute them, use the log gamma function or arbitrary precision arithmetic.
See https://math.stackexchange.com/questions/2455/geometric-proof-of-the-formula-for-simplex-numbers
I have my own formula for this. We, together with my friend Gio made an investigative report concerning this. The formula that we got is [2 raised to (n-1) - 1], where n is the number we are looking for how many addends it has.
Let's try.
If n is 1: its addends are o. There's no two or more numbers that we can add to get a sum of 1 (excluding 0). Let's try a higher number.
Let's try 4. 4 has addends: 1+1+1+1, 1+2+1, 1+1+2, 2+1+1, 1+3, 2+2, 3+1. Its total is 7.
Let's check with the formula. 2 raised to (4-1) - 1 = 2 raised to (3) - 1 = 8-1 =7.
Let's try 15. 2 raised to (15-1) - 1 = 2 raised to (14) - 1 = 16384 - 1 = 16383. Therefore, there are 16383 ways to add numbers that will equal to 15.
(Note: Addends are positive numbers only.)
(You can try other numbers, to check whether our formula is correct or not.)
This can be calculated in O(s+n) (or O(1) if you don't mind an approximation) in the following way:
Imagine we have a string with n-1 X's in it and s o's. So for your example of s=5, n=3, one example string would be
oXooXoo
Notice that the X's divide the o's into three distinct groupings: one of length 1, length 2, and length 2. This corresponds to your solution of <1,2,2>. Every possible string gives us a different solution, by counting the number of o's in a row (a 0 is possible: for example, XoooooX would correspond to <0,5,0>). So by counting the number of possible strings of this form, we get the answer to your question.
There are s+(n-1) positions to choose for s o's, so the answer is Choose(s+n-1, s).
There is a fixed formula to find the answer. If you want to find the number of ways to get N as the sum of R elements. The answer is always:
(N+R-1)!/((R-1)!*(N)!)
or in other words:
(N+R-1) C (R-1)
This actually looks a lot like a Towers of Hanoi problem, without the constraint of stacking disks only on larger disks. You have S disks that can be in any combination on N towers. So that's what got me thinking about it.
What I suspect is that there is a formula we can deduce that doesn't require the recursive programming. I'll need a bit more time though.

Categories

Resources