Broken Calculator — Medium Problem & Solution
A calculator on the CodeKairo help desk is half broken: its display starts at startValue and only two keys still work: Double — multiply the displayed…
- Difficulty: Medium
- Topics: Math, Greedy
- Asked at: Amazon, Google, Microsoft
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
A calculator on the CodeKairo help desk is half broken: its display starts at startValue and only two keys still work:
- Double — multiply the displayed number by 2.
- Decrement — subtract 1 from the displayed number.
Return the minimum number of key presses needed to show target.
Example 1
Input: startValue = 4, target = 13
Output: 4
Explanation: 4 → 8 → 7 → 14 → 13.
Example 2
Input: startValue = 9, target = 3
Output: 6
Explanation: Six decrements.
Example 3
Input: startValue = 5, target = 32
Output: 4
Explanation: 5 → 4 → 8 → 16 → 32.
Constraints
1 <= startValue, target <= 10^9
How to solve Broken Calculator
Reverse the process: from target, the inverse moves are "halve" (when even) and "add 1". Halving as early as possible is always best, which gives a simple greedy.
Approach
- Set
ops = 0. - While
target > startValue: iftargetis odd, increment it; otherwise halve it. Count each step. - Return
ops + (startValue - target)— the remaining gap is closed by adding 1 repeatedly (decrements in the forward direction).
Why it works
An odd target can only be reached forwards by a decrement, so backwards it must be +1. For an even target above startValue, halving first is never worse: doing +1 twice and then halving reaches the same number as halving then +1, with one more step. Repeating this exchange turns any optimal reverse sequence into the greedy one without making it longer.
Complexity
- Time —
O(log target) - Space —
O(1)
Pitfalls
- Simulating forwards with a BFS explodes for values near 10^9.
- When
startValue > targetno doubling is useful — the answer is juststartValue - target. target + 1stays within 32 bits fortarget <= 10^9, so no overflow occurs.
Reference solution
Python
def brokenCalc(startValue: int, target: int) -> int:
ops = 0
while target > startValue:
if target % 2 == 1:
target += 1
else:
target //= 2
ops += 1
return ops + startValue - targetJavaScript
var brokenCalc = function(startValue, target) {
var ops = 0;
while (target > startValue) {
if (target % 2 === 1) target++;
else target /= 2;
ops++;
}
return ops + startValue - target;
};Also on the editorial tab: C, C#, C++, Go, Java, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 307 math problems · the whole catalogue
Learn the technique: Greedy Algorithms