I subscribe to a wonderful newsletter that, among other things, presents readers with a coding challenge every week.

Here’s this week’s question:

Given an array of people objects (where each person has a name and a number of pizza slices they’re hungry for) and a number for the number of slices that the pizza can be sliced into, return the number of pizzas you need to buy.

Example:

``````arr = [{ name: Joe, num: 9 }, { name: Cami, num: 3 }, { name: Cassidy, num: 4 }]
gimmePizza(arr, 8)
2 // 16 slices needed, pizzas can be sliced into 8 pieces, so 2 pizzas should be ordered
``````

Since Rust is basically the only language I write these days (even though I write it poorly), I naturally decided to use Rust.

Here was my first attempt:

``````#![allow(dead_code)]
struct Person<'a> {
name: &'a str,
slices_requested: usize,
}
fn main() {
let persons: Vec<Person> = vec![
Person {
name: "Joe",
slices_requested: 9,
},
Person {
name: "Cami",
slices_requested: 3,
},
Person {
name: "Cassidy",
slices_requested: 4,
},
];

assert_eq!(gimme_pizza(&persons, 8), 2);
println!("Need to order {} pizzas", gimme_pizza(&persons, 8));
}

fn gimme_pizza(persons: &[Person], slices_per_pizza: usize) -> usize {
let mut slices_needed = 0;
for person in persons {
slices_needed += person.slices_requested;
}
if slices_needed % slices_per_pizza == 0 {
slices_needed / slices_per_pizza
} else {
slices_needed / slices_per_pizza + 1
}
}
``````

It works fine, but those first 4 lines of the `gimme_pizza` function bugged me – I shouldn’t have to declare a mutable variable and set it to 0 like that. I knew there was a better way, probably using `map`, to make that summation a bit tighter, but I couldn’t figure out how to get it to work.

Thanks to some help from the Fediverse, I now know this is what I was reaching for:

``````fn gimme_pizza_using_map(persons: &[Person], slices_per_pizza: usize) -> usize {
let slices_needed: usize = persons.iter().map(|person| person.slices_requested).sum();
if slices_needed % slices_per_pizza == 0 {
slices_needed / slices_per_pizza
} else {
slices_needed / slices_per_pizza + 1
}
}
``````

Alternatively, I could have used `fold`, another pair of Fediverse users pointed out. That would have looked like this:

``````fn gimme_pizza_using_fold(persons: &[Person], slices_per_pizza: usize) -> usize {
let slices_needed: usize = persons.iter().fold(0, |running_sum, person| {
running_sum + person.slices_requested
});
if slices_needed % slices_per_pizza == 0 {
slices_needed / slices_per_pizza
} else {
slices_needed / slices_per_pizza + 1
}
}
``````

I’m not sure with I prefer… I’m guessing `fold` is more versatile for cases where you want to do more than summing. And I don’t love that map returns its own object type that you can only do certain things with, whereas fold is more an all-in-one approach.

Separately, I’m curious if there’s a more concise way to go from `slices_needed` to `pizzas_needed`, besides my big ole, 5-line if/else using modulo.