Fun run results table
A village fun run records each finisher as a name and a time in seconds. Produce the results table: fastest first, and when two runners share a time, the one whose name comes first alphabetically is listed first. Number the lines from 1.
Input
The first line is N (1 to 1000). Each of the next N lines holds a name (lowercase letters, no spaces), a space and the time in whole seconds (1 to 100000).
Output
N lines in the form rank. name seconds, for example 1. kit 1498.
Example 1
Input
4 nora 1510 kit 1498 omar 1510 bea 1720
Output
1. kit 1498 2. nora 1510 3. omar 1510 4. bea 1720
kit is fastest. nora and omar tie at 1510 and are ordered by name.
Example 2
Input
3 zed 600 amy 600 max 600
Output
1. amy 600 2. max 600 3. zed 600
Everyone ties, so the table is purely alphabetical.
Constraints
- 1 <= N <= 1000
- Names are 1 to 20 lowercase ASCII letters and are unique
- 1 <= seconds <= 100000
Hints
Hint 1 of 3
Store each runner as a small associative array, ['name' => ..., 'seconds' => ...], in a list.
Hint 2 of 3
usort($runners, $compare) sorts with your own comparison function, which must return a negative number, zero or a positive number.
Hint 3 of 3
$a['seconds'] <=> $b['seconds'] compares the times; when that gives 0, fall back to strcmp($a['name'], $b['name']).
Solution
Show a reference solution and explanation
<?php
$n = (int) trim(fgets(STDIN));
$runners = [];
for ($i = 0; $i < $n; $i++) {
[$name, $seconds] = explode(' ', trim(fgets(STDIN)));
$runners[] = ['name' => $name, 'seconds' => (int) $seconds];
}
usort($runners, function (array $a, array $b): int {
if ($a['seconds'] !== $b['seconds']) {
return $a['seconds'] <=> $b['seconds'];
}
return strcmp($a['name'], $b['name']);
});
foreach ($runners as $index => $runner) {
echo ($index + 1), '. ', $runner['name'], ' ', $runner['seconds'], "\n";
}
Why it works
Sorting by two keys is a matter of writing a comparison that answers the second question only when the first is a tie. The spaceship operator <=> returns -1, 0 or 1 and is exactly what usort expects, and strcmp does the same for strings. usort reindexes the array from 0, so the loop index plus one is the rank. PHP's sorting functions have been stable since PHP 8.0, meaning elements that compare equal keep their input order; here the comparison never returns 0 for two different runners because names are unique, so stability is not needed, but it matters when you sort by one key only.
Lesson for this exercise: Associative Arrays and Sorting in PHP