Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find minimum number of operations required to make one number to another in Python
Given two numbers start and end (where start < end), we need to find the minimum number of operations required to convert start to end using these operations:
- Increment by 1
- Multiply by 2
For example, if start = 5 and end = 11, the output will be 2. We can multiply 5 by 2 to get 10, then add 1 to get 11.
Algorithm
The key insight is to work backwards from the end number. Instead of thinking "how to reach end from start", we think "how did we reach end from start" by reversing the operations:
- If end is odd, we must have added 1, so subtract 1
- If end is even, we could have either multiplied by 2 or added 1. Choose division by 2 (reverse of multiplication) as it reduces the number faster
- Continue until we can reach start by just adding 1s
Implementation
def min_operations(start, end):
operations = 0
# Work backwards from end to start
while end // 2 >= start:
if end % 2 == 1: # end is odd
end -= 1 # subtract 1 (reverse of add 1)
end = end // 2 # divide by 2 (reverse of multiply by 2)
operations += 2
else: # end is even
end = end // 2 # divide by 2 (reverse of multiply by 2)
operations += 1
# Add remaining difference (all increment operations)
operations += (end - start)
return operations
# Test the function
start = 5
end = 11
result = min_operations(start, end)
print(f"Minimum operations from {start} to {end}: {result}")
Minimum operations from 5 to 11: 2
Step-by-Step Trace
Let's trace through the example with start = 5, end = 11:
def min_operations_with_trace(start, end):
operations = 0
print(f"Starting: start={start}, end={end}")
while end // 2 >= start:
if end % 2 == 1: # end is odd
print(f" {end} is odd, subtract 1: {end} -> {end-1}")
end -= 1
print(f" Divide by 2: {end} -> {end//2}")
end = end // 2
operations += 2
print(f" Operations: +2 (total: {operations})")
else: # end is even
print(f" {end} is even, divide by 2: {end} -> {end//2}")
end = end // 2
operations += 1
print(f" Operations: +1 (total: {operations})")
remaining = end - start
operations += remaining
print(f"Remaining difference: {remaining} (add {remaining} increment operations)")
print(f"Total operations: {operations}")
return operations
min_operations_with_trace(5, 11)
Starting: start=5, end=11 11 is odd, subtract 1: 11 -> 10 Divide by 2: 10 -> 5 Operations: +2 (total: 2) Remaining difference: 0 (add 0 increment operations) Total operations: 2
Multiple Examples
# Test with different examples
test_cases = [
(5, 11),
(2, 8),
(1, 7),
(3, 10)
]
for start, end in test_cases:
result = min_operations(start, end)
print(f"From {start} to {end}: {result} operations")
From 5 to 11: 2 operations From 2 to 8: 2 operations From 1 to 7: 4 operations From 3 to 10: 3 operations
How It Works
The algorithm works by reversing the problem. Instead of finding how to go from start to end, we find how we could have arrived at end from start by working backwards. This greedy approach is optimal because:
- When end is even, dividing by 2 reduces the number more efficiently than subtracting 1
- When end is odd, we must subtract 1 first to make it even, then divide
- We stop when further division would make the number smaller than start
Conclusion
This backward greedy approach efficiently finds the minimum operations by working from end to start. The algorithm has O(log n) time complexity since we're essentially halving the number in each iteration.
