Convert a number m to n with minimum operations. The operations allowed were subtraction by 1 and multiplication by 2.
For Eg : 4 and 6. Answer is 2. 1st operation : -1
BFS is not exactly an option here, due to the exponential growth (2 ^ (n - 1) to 2^n
trys are performed, where n is the number of required steps). Instead try to find logic rules for generating the required number.
Let a
be the input-number and b
the number that should be produced.
There are three cases:
a == b
, this case is trivial and just listed for completenessa > b
, the solution is a - b
times substracting by -1
a < b
: This is the more tricky partThe smallest number of operations requires the minimum number of multiplications and substractions. Substractions can easily be minimized due to the following fact: (a - 1) * 2 = a * 2 - 2
. Thus we can easily reduce the number of substractions by any number that is a power of 2 by simply substracting before multiplying.
Since we can only substract and multiply, the minimum number of multiplications is min n => a * 2 ^ n >= b
.
Using this fact we can determine the amount to substract: s = b - 2 ^ n * a
.
The implementation would look like this in pseudocode (can't provide python code):
//using the same variable-names as above in the description
minOp(int a , int b)
//find minimum number of multiplications
int n
for(n = 0 ; a << n < b ; n++)
noop
//find amount to substract
int s = (a << n) - b
for(int i = 0 ; i < n ; i++)
print("(")
print(a)
//calculate operations
while(n > 0)
//calculate number of times we need to substract here (minimization of substractions)
while(s >= 1 << n)
print(" - 1")
s -= 1 << n
print(")")
//divide by two
print(" * 2")
n -= 1
while(s >= 1 << n)
print(" - 1")
s -= 1 << n
print(" = ")
print(b)
This implementation aswell covers the cases a == b
- with n = 0
and s = 0
- and a > b
- with n = 0
and s = a - b
.
A test-run in a java-implementation of the above would produce this output:
(((4) * 2 - 1) * 2 - 1) * 2 = 26
The simplification of the above calculation shows the idea behind this algorithm:
((4 * 2 - 1) * 2 - 1) * 2 = 26
(4 * 2 * 2 - 2 - 1) * 2 = 26
4 * 2 * 2 * 2 - 3 * 2 = 26
32 - 6 = 26
Thanks to @user3386109 for this explanation:
Assume that the start value is A, and the goal value is B. The first step is to create a list of target values starting at B, and proceeding by dividing by 2 (rounding up if necessary). For example, if B is 26, then the list of target values would be 26, 13, 7, 4, 2, 1. If the start value A is any of those target values, then you can easily climb to the goal B (by multiplying by 2 and subtracting 1 if necessary). If A is not one of those values, then you begin by subtracting 1 from A until you reach one of those target values. For example, if A is 6, then two subtractions are needed to reach 4, and then you climb from 4 to 26. If A is 12, five subtractions are needed to reach 7, and so on. Obviously, if A is larger than B, then all you do is subtract one until you reach B