Start learning free

LESSON 246 OF 677 · HELPER FUNCTIONS

Clamp the Values in Kotlin: A Helper Function

Practice Read the full explanation

You get an array of integers nums and two limits, low and high. Return every number moved inside the limits, in the same order.

A number below low becomes low. A number above high becomes high. Any other number stays as it is.

The work is split between two functions. The first one is a helper. It gets one number and the two limits. It returns that number moved inside them. The second one is the function that is graded. It calls the helper on every number.

Don't use a built-in min, max or clamp function. The helper does the comparing.

 

Example 1:

Input: nums = [12, -3, 7, 25], low = 0, high = 20
Output: [12, 0, 7, 20]
Explanation: -3 is below 0, so it becomes 0.
25 is above 20, so it becomes 20.
12 and 7 are already inside the limits.

Example 2:

Input: nums = [-8, -1, 4], low = -5, high = 5
Output: [-5, -1, 4]
Explanation: The limits can be negative too.
-8 is below -5, so it becomes -5.
-1 and 4 stay as they are.

Example 3:

Input: nums = [3, 9, 6], low = 6, high = 6
Output: [6, 6, 6]
Explanation: Both limits are 6, so every number becomes 6.

 

Constraints:

  • nums has at least one number.
  • Every number is between -1000 and 1000.
  • low and high are between -1000 and 1000.
  • low is never greater than high.
STEP 1 OF 7
    Ctrl + Enter to check

    KOTLIN · HELPER FUNCTIONS

    Clamp All in Kotlin, explained

    Problem overview

    The function clampAll gets an array of integers nums and two limits, low and high. It returns every number moved inside the limits, in the same order. A number below low becomes low, a number above high becomes high, and any other number stays as it is. The limits are never reversed: low is never greater than high.

    The lesson splits the work between two functions. clamp is a helper: it gets one number and the two limits and returns that number moved inside them. clampAll is the function the tests call, and it calls the helper on every number. The lesson asks you to do the comparing yourself in the helper, without a built-in min, max or clamp function.

    With nums = [12, -3, 7, 25], low = 0 and high = 20 the answer is [12, 0, 7, 20]: -3 is below 0, 25 is above 20, and 12 and 7 are inside.

    Why a helper

    Clamping one number is a small problem on its own. Writing it as a function lets you test it alone and keeps the loop easy to read: the loop only says "do this to every number", and the helper says what "this" is. Kotlin lets two functions in the same class call each other by name.

    Step by step

    1. In clamp, if x is less than low, return low.
    2. Below that, if x is greater than high, return high.
    3. After both checks, return x. Only a number between the limits gets here, and it stays as it is. No else is needed, because each return leaves the function.
    4. In clampAll, create an empty mutableListOf<Int>() named clamped, in a val. The variable never changes to another list, but the list itself can grow.
    5. Loop with for (num in nums), one turn per number.
    6. Inside, add the helper's answer: clamped.add(clamp(num, low, high)). The loop needs no if of its own.
    7. After the loop, return clamped.

    The solution in Kotlin

    class Solution {
        fun clamp(x: Int, low: Int, high: Int): Int {
            if (x < low) {
                return low
            }
            if (x > high) {
                return high
            }
            return x
        }
    
        fun clampAll(nums: IntArray, low: Int, high: Int): List<Int> {
            val clamped = mutableListOf<Int>()
            for (num in nums) {
                clamped.add(clamp(num, low, high))
            }
            return clamped
        }
    }
    

    Two Kotlin details. The input is an IntArray, which you can loop over directly, while the answer is a List<Int> that you build up. And the helper's parameters are read-only: you return a value instead of changing x.

    Why the order of the checks is safe

    The two if statements do not interfere because low is never greater than high. A number cannot be both below low and above high. If it is below low, the helper returns low and never looks at the second check. If it is above high, the first check is false and the second one returns high. A number on a limit, such as 6 with both limits 6, fails both checks and comes back as it is, which is also the limit. When both limits are equal, every number ends up equal to that limit: clamp(5, 6, 6) and clamp(6, 6, 6) both return 6.

    A built-in that does the same

    Kotlin's standard library has coerceIn: 25.coerceIn(0, 20) is 20, (-3).coerceIn(0, 20) is 0 and 7.coerceIn(0, 20) is 7. The lesson asks you to write the comparing yourself so you see how a helper works, but it is good to know the library has it. Combined with map, it would even replace the loop: listOf(12, -3, 7, 25).map { it.coerceIn(0, 20) } gives [12, 0, 7, 20].

    Testing

    The helper alone, with limits 0 and 20: clamp(25, 0, 20) returns 20, clamp(-3, 0, 20) returns 0 and clamp(7, 0, 20) returns 7. The tests print lists as values separated by spaces. The three examples print:

    12 0 7 20
    -5 -1 4
    6 6 6
    

    The second uses negative limits, -5 and 5, so -8 becomes -5. In the third, both limits are 6, so every number becomes 6.

    Complexity

    The helper does a constant amount of work, and the loop calls it once per number. So the time grows in step with the length of nums. The answer is a new list of the same length, which is the only extra space. The input array is not changed: clampAll returns a new list instead of writing the clamped numbers back into nums.

    Common mistakes

    • Returning inside the loop. Only the first number would come back. Return after the loop.
    • Swapping the limits in the call. clamp(num, high, low) compiles but makes the helper treat the upper limit as the lower one.
    • Writing the loop's checks again. The helper already does the comparing; calling it keeps the loop to one line.
    • Trying to assign to the parameter. Writing x = low inside the helper does not compile, because Kotlin parameters are read-only. Return the value instead, as the solution does.
    • Using else if but forgetting the plain return. Every path through the helper must end in a return, including the one for a number already inside the limits.
    • Forgetting the final return x. Kotlin reports an error because the function must return an Int on every path.
    Keep going with Kotlin500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free