Start learning free

LESSON 276 OF 679 · TUPLES, SORTING & BUILT-INS

Trimmed Total in Rust: sum, min and max

Practice Read the full explanation

You get a Vec 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

    RUST · TUPLES, SORTING & BUILT-INS

    Trimmed Total in Rust, explained

    Problem overview

    The function trimmed_total receives a vector of integers, nums, with 3 to 100 numbers between -1000 and 1000. It returns their sum without the smallest and the largest value. This is how some contests score: each judge gives a number, and the lowest and highest are dropped so that one very strict or very kind judge cannot decide alone.

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

    For [7, 9, 6, 8, 10] the answer is 24: the 6 and the 10 are dropped, and 7 + 9 + 8 remain. For [5, 1, 5, 9, 1] it is 11, because only one 1 and the 9 are dropped. For [-4, 3, -2] it is -2.

    Approach

    Add everything, then take away the two extremes. Subtracting the smallest value once and the largest value once removes exactly one smallest and one largest item, even when those values repeat. The iterator methods sum(), min() and max() do the work, so no loop is needed.

    Step by step

    1. Total. let total: i32 = nums.iter().sum(); adds the numbers. The type on total is required: sum() can produce several number types, and without a type the compiler reports "type annotations needed".
    2. Smallest. nums.iter().min() returns an Option, because an empty vector has no smallest value. unwrap() takes the value out; here it always exists, since there are at least 3 numbers. The value is a reference, so a * in front gives the plain number.
    3. Largest. The same chain with max(). When the largest value appears twice, max() still gives that value once.
    4. Return total - smallest - largest.

    The solution in Rust

    impl Solution {
        fn trimmed_total(nums: Vec<i32>) -> i32 {
            let total: i32 = nums.iter().sum();
            let smallest = *nums.iter().min().unwrap();
            let largest = *nums.iter().max().unwrap();
            return total - smallest - largest;
        }
    }

    The sum is at most 100 times 1000 in size, so an i32 holds it without overflow. The function is safe to unwrap() only because of the constraint of at least 3 numbers; on an empty vector the same code would panic.

    Another way

    Sorting a copy puts the extremes at both ends, so the middle slice is the answer:

    let mut sorted = nums.clone();
    sorted.sort();
    let middle: i32 = sorted[1..sorted.len() - 1].iter().sum();

    It gives 24, 11 and -2 on the three examples, like the lesson's version. The solution above is simpler and does not need to sort or copy anything. Sorting would also reorder the numbers, which this problem does not need.

    The three examples give:

    24
    11
    -2

    Edge cases and common mistakes

    • Removing every copy. Filtering out all values equal to the smallest would drop both 1s in the second example and give 10, not 11. Subtracting each extreme once is the right rule.
    • Negative numbers. The third example subtracts -4 and 3 from -3, and the arithmetic works the same way.
    • Calling min() on an empty vector. It returns None, and unwrap() on None panics. The constraint of at least 3 numbers rules this out here.
    Keep going with Rust500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free