Start learning free

LESSON 51 OF 348 · CALCULATIONS - CHALLENGES

Buy Candy in Kotlin: Integer Division and One More Box

Practice Read the full explanation

A box of candy costs price dollars. You have balance dollars. Compute the number of boxes of candy you can buy and return how many more dollars you need to buy one more box of candy.

Example:

Input: price = 4, balance = 9

Output: 3

Explanation:
You can buy two boxes of candy that costs 4 * 2 = 8 dollars.
If you would have 12 dollars you could buy 3 boxes (one more), so you would need 3 more dollars.
Hints:

The number of boxes we can buy is the integer part of the division of balance by price. Let's store this number in a variable boxes.

We want to buy one more box, so a total of boxes + 1 boxes, which require (boxes + 1) * price dollars. Let's store this product into another variable balanceNeeded.

Finally the answer is the difference between balanceNeeded and balance.
STEP 1 OF 4
    Ctrl + Enter to check

    KOTLIN · CALCULATIONS - CHALLENGES

    Buy Candy in Kotlin, explained

    Problem overview

    A box of candy costs price dollars, and you have balance dollars. The function buyCandy must return how many more dollars you would 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, with 1 dollar left over. 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 easier in three small questions:

    1. How many boxes can I buy now?
    2. What would one more box than that cost in total?
    3. How far is that total from what I have?

    The first answer is "balance divided by price, dropping the remainder". The second is that count plus one, times the price. The third is a subtraction. There's no loop and no condition, just three lines of arithmetic.

    The last step has a pleasant property: the answer is never 0. If you have exactly 8 dollars and each box costs 4, you can buy two boxes with nothing left over, and one more box still costs a full 4 dollars, so the answer is 4. A balance of 9 leaves 1 dollar over, which is why the answer for that case is 3 and not 4.

    Step by step

    1. Count the whole boxes. Declare boxes as balance / price. When both operands are integers, Kotlin's / drops the fractional part, so 9 / 4 is 2, which is exactly the number of whole boxes.
    2. Price one more box. Declare balanceNeeded as (boxes + 1) * price. The parentheses make the addition happen first. Without them, boxes + 1 * price would multiply before it adds and give a different number.
    3. Find the gap. Declare extraBalance as balanceNeeded - balance. This is the money you are missing.
    4. Return it. The challenge asks for that gap, so extraBalance is the result.

    The three variables are declared with val because none of them changes after it is set.

    The solution in Kotlin

    class Solution {
        fun buyCandy(price: Int, balance: Int): Int {
            val boxes = balance / price
            val balanceNeeded = (boxes + 1) * price
            val extraBalance = balanceNeeded - balance
            return extraBalance
        }
    }
    

    Details worth knowing:

    • Integer division truncates. Both balance and price are Int, so the division produces an Int with the fraction dropped. For positive numbers that is rounding down. It does not produce 2.25 for 9 / 4.
    • Type inference. No variable has a written type. Kotlin infers Int from the expressions, so val boxes = balance / price is the same as val boxes: Int = balance / price.
    • val can't be reassigned. Each name is set once. Trying to assign boxes again later is a compile error.
    • The intermediate names are optional. The whole function could be one line, return ((balance / price) + 1) * price - balance. Naming the steps makes each one easy to read and check.

    Complexity

    The function does one division, one addition, one multiplication and one subtraction, whatever the inputs are. It runs in constant time, O(1), and uses constant extra space, O(1).

    Edge cases and common mistakes

    • Exact multiples. With price = 4 and balance = 8, boxes is 2 and balanceNeeded is 12, so the answer is 4, a whole price. Returning 0 here is a common slip.
    • Not enough for any box. With price = 4 and balance = 3, boxes is 0, balanceNeeded is 4 and the answer is 1.
    • Zero balance. With balance = 0, the answer is the full price.
    • A price of 0. Dividing an Int by zero throws an ArithmeticException with the message / by zero. The challenge doesn't ask for this case, but it explains why a price is expected to be positive.
    • Forgetting the parentheses around boxes + 1, which changes the order of operations.
    • Using the remainder instead. The remainder balance % price is the money left over, and the missing amount is price - balance % price. That also works, but it is a different route from the one this lesson takes.

    Testing

    • buyCandy(4, 9) returns 3.
    • buyCandy(4, 8) returns 4.
    • buyCandy(4, 3) returns 1.
    • buyCandy(4, 0) returns 4.
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free