Storing values from recursive function calls

Beginner question. I have just finished reading the first few chapters of the book and trying out some simple problems.

This program generates all combinations of n dice rolls, and prints their totals. For example, for 3 dice rolls on a dice with sides 1, 2, 3, and 4, this is the output:

[1, 1, 1] - total = 3
[1, 1, 2] - total = 4
[1, 1, 3] - total = 5
[1, 1, 4] - total = 6
[1, 2, 1] - total = 4
...
[4, 4, 1] - total = 9
[4, 4, 2] - total = 10
[4, 4, 3] - total = 11
[4, 4, 4] - total = 12

This is the program:

const DICE: [i32; 4] = [1, 2, 3, 4]; // Your dice sides from smallest to largest
pub fn start() {
    let rolls = 3;
    combos(rolls, 0, Vec::new());
}
// rolls - the number of times the dice is rolled
// current - the current roll index (keeps track of number of rolls)
// output - the vector for storing the outcome of each roll
fn combos(rolls: i32, current: i32, mut output: Vec<i32>) {
    if current >= rolls {
        let sum: i32 = output.iter().sum();
        println!("{:?} - total = {sum}", output);
        return;
    }
    for n in 1..=DICE[DICE.len() - 1] {
        output.push(n);
        combos(rolls, current + 1, output.clone());
        output.pop();
    }
}

What I am trying to do is store those sums in a vector rather than just printing them. A global vector where I could push the sums would do the job, but it's probably not the right approach. I am also pretty sure that cloning a vector for every recursive call is probably not a good idea either. Is there a way to avoid this?

Thanks

An immediate solution would be to just pass a mutable reference to the vector instead.

However, pushing to and then immediately popping from the vector seems very much like an anti-pattern. The DICE array looks redundant, too. It would be much easier to simply keep track of how many rolls still remain. Like this:

fn roll_sums(rolls: u32, partial_sum: u32, outsum: &mut Vec<u32>) {
    if let Some(remaining) = rolls.checked_sub(1) {
        for side in 1..=4 {
            roll_sums(remaining, partial_sum + side, outsum);
        }
    } else {
        outsum.push(partial_sum);
    }
}
5 Likes

Very nice, thank you @H2CO3.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.