Problem overview
A box of candy costs price dollars and you have balance dollars. The function buyCandy must return how many more dollars you need to afford one more box than you can afford now.
Take price = 4 and balance = 9. Two boxes cost 8 dollars, so you can buy two. A third box would bring the total to 12 dollars, and you have 9, so you are 3 dollars short. The answer is 3.
Approach
The question is really "what is the next multiple of price above balance, and how far away is it?" There is no need for a loop that buys boxes one at a time. Three small calculations give the answer:
- How many whole boxes does
balancecover? - What does one more box than that cost in total?
- How far is that total from
balance?
Step by step
- Count the whole boxes. Divide
balancebyprice. When both operands are integers, Go's/drops the fractional part, which is exactly the number of whole boxes:9 / 4is2. Store it inboxeswith:=. - Price one more box. You want
boxes + 1boxes, which cost(boxes + 1) * price. The parentheses make the addition happen before the multiplication. For the example this is3 * 4 = 12, stored inbalanceNeeded. - Find the gap. Subtract the money you have:
balanceNeeded - balanceis12 - 9 = 3. Store it inextraBalance. - Return it. The gap is the answer, so
return extraBalance.
The solution in Go
func buyCandy(price int, balance int) int {
boxes := balance / price
balanceNeeded := (boxes + 1) * price
extraBalance := balanceNeeded - balance
return extraBalance
}
Some Go details matter here:
- Integer division. Because
balanceandpriceare bothint, the result is anintwith the fraction cut off. With non-negative numbers this is the same as rounding down. Go does not turn it into a decimal behind your back. - Short declarations. Each
:=creates a new variable and infers its type, hereint, from the right-hand side. Every variable you declare must be used. All three are read by a later line, so the compiler accepts them. - Division by zero. A price of
0would makebalance / pricepanic at run time for integers. A box of candy has a positive price, so the function does not guard against it.
A shorter route
The same answer can be found with the remainder operator. balance % price is the money left over after buying as many boxes as possible, and price - balance % price is what that leftover lacks to make one more box. For price = 4 and balance = 9 this is 4 - 1 = 3. The three-variable version in the lesson is longer, but each line has a clear meaning, which makes it easier to check by hand.
Complexity
The function does one division, one multiplication, one addition and one subtraction, so it runs in constant time, O(1), and uses constant space.
Edge cases and common mistakes
- Balance is an exact multiple of the price. With
price = 4andbalance = 8,boxesis2andbalanceNeededis12, so the result is4, a full price. It is never0, because you are asked about one more box than you can already afford. - Balance smaller than the price. With
price = 4andbalance = 3,boxesis0and the answer is4 - 3 = 1. - Zero balance. With
price = 5andbalance = 0, no boxes and the answer is the full5. - Missing parentheses.
boxes + 1 * pricemultiplies first and gives the wrong total. Use(boxes + 1) * price. - Returning the cost instead of the gap.
balanceNeededis the total price, not the shortfall.
Small inputs worth trying: buyCandy(4, 9) gives 3, buyCandy(4, 8) gives 4, buyCandy(4, 3) gives 1 and buyCandy(5, 0) gives 5.