Student Grade Book
Problem
Build a small grade book. Commands: add <name> <score> stores one score for a student and prints ok. average <name> prints the whole-number average of that student (rounded down), or unknown if the student has no scores. best prints the name of the student with the highest average; on a tie the name that comes first alphabetically wins; print none when the book is empty.
Constraints
- 1 <= commands <= 10^4
- 0 <= score <= 100
Examples
Input
add amit 80 add amit 91 average amit
Output
ok ok 85
Solutions
Keeping the data in a small class (GradeBook) separates the rules from the command reading. Sorting the names first makes the tie rule easy: only a strictly better average replaces the current best.
/*
* Problem : Process lines.
* Input : Several lines.
* Output : One result per command.
* Approach: A small class holds the data.
* Time : O(n log n)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// Step 1: The grade book keeps all scores of each student. A TreeMap keeps names in alphabetical order.
static class GradeBook {
private final java.util.TreeMap<String, java.util.List<Integer>> scores = new java.util.TreeMap<>();
void add(String name, int score) {
scores.computeIfAbsent(name, key -> new java.util.ArrayList<>()).add(score);
}
// Step 2: Whole-number average. The sum of non-negative scores divided by the count rounds down.
private int averageOf(String name) {
int sum = 0;
for (int score : scores.get(name)) {
sum += score;
}
return sum / scores.get(name).size();
}
String average(String name) {
return scores.containsKey(name) ? String.valueOf(averageOf(name)) : "unknown";
}
// Step 3: Walk the names in alphabetical order. Only a strictly higher average replaces the best one.
String best() {
String winner = "none";
int top = -1;
for (String name : scores.keySet()) {
if (averageOf(name) > top) {
top = averageOf(name);
winner = name;
}
}
return winner;
}
}
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
GradeBook book = new GradeBook();
String[] output = new String[lines.length];
for (int i = 0; i < lines.length; i++) {
String[] part = lines[i].split(" ");
// Step 4: One command gives one output line.
if (part[0].equals("add")) {
book.add(part[1], Integer.parseInt(part[2]));
output[i] = "ok";
} else if (part[0].equals("average")) {
output[i] = book.average(part[1]);
} else {
output[i] = book.best();
}
}
return output;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (1)
- Why is a TreeMap handy here?