Staff per department
A hospital roster lists one staff member per line as a name followed by a department. Management wants a headcount per department, with the busiest department first. Where two departments have the same headcount, list them in alphabetical order.
Read the roster, group it by department and print the counts.
Input
The first line is an integer n. Each of the next n lines is name department, two words of lower-case letters separated by one space.
Output
One line per distinct department in the form department: count, ordered by count descending, then by department name ascending.
Example 1
Input
6 mara surgery tomas radiology ines surgery kofi pharmacy lena radiology omar surgery
Output
surgery: 3 radiology: 2 pharmacy: 1
Surgery has three people, radiology two and pharmacy one.
Example 2
Input
3 abe wards bea theatre cal reception
Output
reception: 1 theatre: 1 wards: 1
All three departments tie on one person each, so they are listed alphabetically.
Constraints
- 1 <= n <= 200
- Names and departments are 1 to 20 lower-case letters
Hints
Hint 1 of 3
You only need the department from each line, so store just parts[1].
Hint 2 of 3
GroupBy(d => d) gives one group per distinct department; each group has a Key and a Count().
Hint 3 of 3
Chain OrderByDescending(count) and then ThenBy(name) so the alphabetical order only decides ties.
Solution
Show a reference solution and explanation
int count = int.Parse(Console.ReadLine()!);
var departments = new List<string>();
for (int i = 0; i < count; i++)
{
string[] parts = Console.ReadLine()!.Split(' ');
departments.Add(parts[1]);
}
var ranked = departments
.GroupBy(d => d)
.Select(g => new { Name = g.Key, Count = g.Count() })
.OrderByDescending(x => x.Count)
.ThenBy(x => x.Name, StringComparer.Ordinal);
foreach (var entry in ranked)
{
Console.WriteLine($"{entry.Name}: {entry.Count}");
}
Why it works
LINQ expresses the whole report as a pipeline: group, project each group to a name and a count, then sort. OrderByDescending followed by ThenBy is the idiom for a primary key with a tie-breaker; a second OrderBy instead of ThenBy would throw the first ordering away. Passing StringComparer.Ordinal makes the alphabetical order depend only on character codes, not on the machine's culture settings, which is what you want for reproducible output. The query is lazy: nothing is grouped or sorted until the foreach starts pulling results.