Problem overview
A box of candy costs price dollars and you have balance dollars. The method buyCandy returns how many more dollars you need to afford one more box than you can buy now.
In the example, price = 4 and balance = 9. Nine dollars buy two boxes, which cost 8. A third box would bring the total to 12, so you need 3 more dollars. The answer is 3.
Approach
The question has three parts, and each is one short calculation:
- How many whole boxes does the balance cover?
- What would one more box than that cost in total?
- How far is that total from the money you have?
The first part is integer division. Dividing two Int values in Scala gives an Int and drops the fractional part, so 9 / 4 is 2, exactly the number of whole boxes. The remaining parts are a multiplication and a subtraction.
One consequence deserves attention. If the balance is an exact multiple of the price, you can already buy balance / price boxes with nothing left over. One more box still costs a full price, so the answer is price, never 0. With price = 4 and balance = 8, the answer is 4.
Step by step
- Count the whole boxes. Declare a
valnamedboxeswithbalance / price. Avalis an immutable value: once set, it can't be reassigned, which is right for a result you only read afterwards. - Price one more box than that. Declare
balanceNeededas(boxes + 1) * price. The parentheses make the addition happen before the multiplication; without them,boxes + 1 * pricewould multiply first. - Find the gap. Declare
extraBalanceasbalanceNeeded - balance. This is the money still missing. - Return it as the result of the method.
The solution in Scala
class Solution {
def buyCandy(price: Int, balance: Int): Int = {
val boxes = balance / price
val balanceNeeded = (boxes + 1) * price
val extraBalance = balanceNeeded - balance
return extraBalance
}
}
Scala details:
- Inferred types. None of the three
vallines names a type. Scala infersIntfrom the right-hand side. You could writeval boxes: Int = balance / priceand nothing would change. - Integer division truncates. Both operands are
Int, so the result is cut toward zero. For the non-negative values in this problem that is the same as rounding down. returnis optional. The last expression of the block is its value, so ending the method withextraBalancealone is equivalent.
Complexity
Time: O(1). The method performs a fixed number of arithmetic operations whatever the input values are.
Space: O(1). It stores three integers.
Edge cases and common mistakes
- Exact multiples.
buyCandy(4, 8)is4, not0. Computingboxes * price - balanceinstead would give0here and a negative number everywhere else. - Not enough for one box.
buyCandy(5, 3)is2:boxesis0, and one box costs 5, which is 2 more than you have. A balance of0works too:buyCandy(4, 0)is4. - Forgetting the parentheses.
boxes + 1 * pricecomputesboxes + price, which is wrong unlesspriceis1. - Division by zero. A price of
0makesbalance / pricethrow anArithmeticExceptionforIntvalues. The problem implies a positive price. - Using a decimal division. Converting to
Doublewould keep the fraction (2.25boxes) and break the count of whole boxes.
Testing
price = 4,balance = 9gives3.price = 4,balance = 8gives4.price = 5,balance = 3gives2.price = 4,balance = 0gives4.
