Start learning free

LESSON 251 OF 679 · HELPER FUNCTIONS

Biggest Digit Sum in Rust: A Digit-Sum Helper

Practice Read the full explanation

You get an array of integers nums. Return the number whose digits add up to the most.

The digit sum of 472 is 4 + 7 + 2 = 13. If two numbers have the same digit sum, return the one that comes first.

The work is split between two functions. The first one is a helper. It gets one number and returns the sum of its digits. The second one is the function that is graded. It uses the helper to compare the numbers.

 

Example 1:

Input: nums = [472, 95, 1000]
Output: 95
Explanation: The digit sums are 13, 14 and 1.
95 has the biggest one: 9 + 5 = 14.

Example 2:

Input: nums = [19, 55, 28]
Output: 19
Explanation: All three digit sums are 10.
19 comes first, so it wins the tie.

Example 3:

Input: nums = [0, 7]
Output: 7
Explanation: The digit sum of 0 is 0.
The digit sum of 7 is 7.

 

Constraints:

  • nums has at least one number.
  • Every number is between 0 and 109.
  • Return the number itself, not its digit sum.
STEP 1 OF 10
    Ctrl + Enter to check

    RUST · HELPER FUNCTIONS

    Biggest Digit Sum in Rust, explained

    Problem overview

    This lesson has two functions. The helper digit_sum receives a whole number n and returns the sum of its digits: for 472 that is 4 + 7 + 2 = 13. The function that is tested, biggest_digit_sum, receives a vector nums and returns the number whose digits add up to the most. If two numbers have the same digit sum, the one that comes first wins. It returns the number itself, not its digit sum.

    For [472, 95, 1000] the digit sums are 13, 14 and 1, so the answer is 95. For [19, 55, 28] all three sums are 10, so the first number, 19, wins the tie. For [0, 7] the sums are 0 and 7, so the answer is 7. Every number is between 0 and 1,000,000,000, and the vector has at least one number.

    Approach

    Split the task. The helper takes digits off a number one at a time: the remainder after dividing by 10 is the last digit, and dividing by 10 drops it. Repeat until nothing is left. Then biggest_digit_sum is the usual "running best": keep the winner so far and replace it only when a number has a strictly bigger digit sum.

    Step by step

    1. In digit_sum, function parameters are immutable in Rust, so the loop can't change n. Declare a mutable copy: let mut num = n;.
    2. Declare let mut total = 0;. For n = 0 the loop never runs and 0 is the right answer.
    3. Loop while num > 0. Each turn removes one digit, so num reaches 0 when all digits are gone.
    4. Inside, add num % 10 (the last digit; 472 % 10 is 2) to total.
    5. Still inside, set num = num / 10. Integer division drops the remainder, so 472 becomes 47. Without this line the loop never ends.
    6. After the loop, return total.
    7. In biggest_digit_sum, start best at nums[0], the first number.
    8. Loop over &nums. If Self::digit_sum(*num) > Self::digit_sum(best), set best = *num.
    9. Return best.

    The solution in Rust

    impl Solution {
        fn digit_sum(n: i32) -> i32 {
            let mut num = n;
            let mut total = 0;
            while num > 0 {
                total += num % 10;
                num = num / 10;
            }
            return total;
        }
        fn biggest_digit_sum(nums: Vec<i32>) -> i32 {
            let mut best = nums[0];
            for num in &nums {
                if Self::digit_sum(*num) > Self::digit_sum(best) {
                    best = *num;
                }
            }
            return best;
        }
    }
    

    Rust details

    • Mutability. A variable declared with plain let can't be changed, and neither can a parameter. Writing let total = 0; and then total += ..., or assigning to n directly, gives the compiler errors cannot assign twice to immutable variable `total` and cannot assign to immutable argument `n`. That is why the solution copies n into let mut num and uses let mut total.
    • Division. Both operands are i32, so / drops the remainder: 472 / 10 is 47, and 7 / 10 is 0.
    • Ties. The comparison uses >, not >=. On a tie, best is not replaced, so the number that came first keeps the place.
    • The first number compares with itself. The loop starts at the first number again. That comparison is never "greater", so it does no harm.

    Watching the loops work

    Inside the helper, the digits of 472 come off from the right:

    num=472  digit=2  total=2
    num=47   digit=7  total=9
    num=4    digit=4  total=13
    

    After the third turn num is 0, the loop stops and 13 is returned. In biggest_digit_sum, best changes only when a strictly bigger digit sum shows up:

    [472, 95, 1000]
      num=472  sum=13  best=472
      num=95   sum=14  best=95
      num=1000 sum=1   best=95
    [19, 55, 28]
      num=19   sum=10  best=19
      num=55   sum=10  best=19
      num=28   sum=10  best=19
    

    In the second vector every sum is 10, nothing is strictly bigger than the first, and 19 stays the winner.

    Why the helper is separate

    The comparison digit_sum(*num) > digit_sum(best) reads almost like the task itself. All the digit-taking work stays inside the helper, so the loop in biggest_digit_sum only has to compare. Note that the helper is called twice per number, once for the candidate and once for the current best. That is a little wasteful, but with small inputs it costs nothing, and it keeps the code short. Storing the best sum in its own variable would avoid the repeat call.

    Trying it

    biggest_digit_sum([472, 95, 1000])  ->  95
    biggest_digit_sum([19, 55, 28])     ->  19
    biggest_digit_sum([0, 7])           ->  7
    digit_sum(472), digit_sum(0), digit_sum(1000000000), digit_sum(999999999)  ->  13, 0, 1, 81
    

    The largest allowed value, 1,000,000,000, fits in an i32 and has a digit sum of 1. A nine-digit number made of 9s has the biggest possible sum here, 81. So the sums are always small, and total can't overflow.

    A variant that calls the helper once per number

    If you want to avoid the repeated call, keep the best digit sum next to the best number. This version gives the same answers on the three examples (95, 19 and 7), and it follows the same rule: it replaces the winner only when the new sum is strictly bigger.

    fn biggest_digit_sum(nums: Vec<i32>) -> i32 {
        let mut best = nums[0];
        let mut best_sum = Self::digit_sum(best);
        for num in &nums {
            let s = Self::digit_sum(*num);
            if s > best_sum {
                best = *num;
                best_sum = s;
            }
        }
        return best;
    }
    

    Both versions are correct.

    Common mistakes

    • Returning the digit sum. The task wants the number itself. With [472, 95, 1000] the answer is 95, not 14.
    • Using >= for the comparison. The last of several tied numbers would win instead of the first. [19, 55, 28] would give 28.
    • Forgetting to divide by 10. num never changes and the loop runs forever.
    • Making the number the "biggest" itself. A larger number does not mean a larger digit sum: 1000 is far bigger than 95, but its digits add up to 1.
    Keep going with Rust500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free