Ingredient tally for the week
A bakery's weekly plan lists the ingredients each recipe needs, one per line as a name and a quantity in grams. The same ingredient appears under several recipes. Add up the quantity of every ingredient and print one line per distinct ingredient as name: total, sorted alphabetically by name.
Input
The first line is N (1 to 500). Each of the next N lines holds an ingredient name (lowercase letters only), a space and an integer quantity from 1 to 100000.
Output
One line per distinct ingredient, name: total, in alphabetical order of the name.
Example 1
Input
4 flour 500 sugar 200 flour 250 butter 100
Output
butter: 100 flour: 750 sugar: 200
Flour appears twice and adds up to 750. The output is ordered butter, flour, sugar.
Example 2
Input
3 salt 5 salt 5 salt 5
Output
salt: 15
One distinct ingredient, three lines added together.
Constraints
- 1 <= N <= 500
- Names are 1 to 30 lowercase ASCII letters
- 1 <= quantity <= 100000
Hints
Hint 1 of 3
Use the name as the array key: $totals[$name] holds the running total for that ingredient.
Hint 2 of 3
The first time a name appears the key does not exist yet; $totals[$name] ?? 0 gives 0 in that case.
Hint 3 of 3
ksort($totals) sorts the array by key in place; then foreach ($totals as $name => $total) prints in that order.
Solution
Show a reference solution and explanation
<?php
$n = (int) trim(fgets(STDIN));
$totals = [];
for ($i = 0; $i < $n; $i++) {
[$name, $qty] = explode(' ', trim(fgets(STDIN)));
$totals[$name] = ($totals[$name] ?? 0) + (int) $qty;
}
ksort($totals);
foreach ($totals as $name => $total) {
echo "$name: $total\n";
}
Why it works
An associative array is PHP's map: each ingredient name is a key and the value is the running total. The null coalescing operator ?? handles the first sighting of a name without a separate isset check, which avoids the undefined array key warning PHP 8 raises when you read a key that is not there. ksort() sorts by key, which is the alphabetical order the output requires; sort() would have thrown the keys away and asort() would have sorted by the totals. Because a foreach over an array visits entries in their stored order, sorting once before the loop is all it takes.
Lesson for this exercise: Associative Arrays and Sorting in PHP