Start learning free

LESSON 274 OF 677 · TUPLES, SORTING & BUILT-INS

Trimmed Total in Scala: Sum Without the Smallest and Largest

Practice Read the full explanation

You get an ArrayBuffer of integers nums. Return their sum without the smallest and the largest value.

Some contests score this way. Each judge gives a score. The lowest and the highest score are dropped. So one very strict or very kind judge can't decide alone.

Drop only one smallest value and one largest value. If the smallest value appears twice, the other copy still counts. The same goes for the largest value.

 

Example 1:

Input: nums = [7, 9, 6, 8, 10]
Output: 24
Explanation: The smallest value is 6 and the largest is 10.
The rest add up to 7 + 9 + 8 = 24.

Example 2:

Input: nums = [5, 1, 5, 9, 1]
Output: 11
Explanation: The smallest value, 1, appears twice.
Only one 1 is dropped, and so is the 9.
5 + 5 + 1 = 11.

Example 3:

Input: nums = [-4, 3, -2]
Output: -2
Explanation: -4 is the smallest value and 3 is the largest.
Only -2 is left.

 

Constraints:

  • nums has 3 to 100 numbers.
  • Every number is between -1000 and 1000.
STEP 1 OF 4
    Ctrl + Enter to check

    SCALA · TUPLES, SORTING & BUILT-INS

    Trimmed Total in Scala, explained

    Problem overview

    trimmedTotal gets an ArrayBuffer[Int] called nums with 3 to 100 numbers, each between -1000 and 1000. It returns their sum without one smallest value and one largest value. Contests score this way: each judge gives a score, and the lowest and highest are dropped, so one very strict or very kind judge can't decide alone.

    Only one smallest and one largest value are dropped. If the smallest value appears twice, the other copy still counts.

    • [7, 9, 6, 8, 10] gives 24, which is 7 + 9 + 8.
    • [5, 1, 5, 9, 1] gives 11: one 1 and the 9 are dropped, leaving 5 + 5 + 1.
    • [-4, 3, -2] gives -2.

    Approach

    Add everything, then take the smallest and the largest off the total once each. Subtracting a value once removes exactly one copy of it, which is the rule for repeats. The built-ins sum, min and max do each piece in one call.

    Removing values from the buffer is the approach to avoid. A filter such as nums.filter(n => n != nums.min && n != nums.max) drops every copy. On [5, 1, 5, 9, 1] it leaves 5 + 5 = 10 instead of 11.

    In the first example, [7, 9, 6, 8, 10], the smallest is 6 and the largest is 10, so the remaining three numbers are 7, 9 and 8. Their sum is 24. The order of the numbers in the buffer doesn't matter for this problem, because a sum doesn't depend on order.

    Step by step

    1. Store the sum of all the numbers in a val named total.
    2. Store the smallest number in smallest, with min.
    3. Store the largest number in largest, with max.
    4. Return total - smallest - largest.

    For [5, 1, 5, 9, 1] the three built-ins give a total of 21, a smallest of 1 and a largest of 9. Then 21 - 1 - 9 is 11, which matches the example.

    The solution in Scala

    class Solution {
        def trimmedTotal(nums: ArrayBuffer[Int]): Int = {
            val total = nums.sum
            val smallest = nums.min
            val largest = nums.max
            return total - smallest - largest
        }
    }
    

    min and max return one value each, even when it appears several times, so each is subtracted once. With three or more numbers, the buffer is never empty, so min and max are safe. With three equal numbers, such as [3, 3, 3], the function gives 3: the total 9 minus one 3 minus another 3. That is correct, because one smallest and one largest value are dropped, and they are two different items.

    The sum stays far from the limit of Int: at most 100 numbers of at most 1000 each.

    Testing

    [7, 9, 6, 8, 10]   24
    [5, 1, 5, 9, 1]    11
    [-4, 3, -2]        -2
    [3, 3, 3]          3
    

    Common mistakes

    • Removing every copy. A filter that drops all copies of the smallest and largest values gives the wrong answer when they repeat, as shown above.
    • Subtracting only one extreme. Both are dropped.
    • Sorting and slicing off the ends. That also works: nums.sorted.slice(1, nums.length - 1).sum gives 11 for the second example, because the sorted buffer is ArrayBuffer(1, 1, 5, 5, 9) and the slice skips its first and last items. But it does more work than three built-in calls.
    Keep going with Scala500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free