#include <bits/stdc++.h>
using namespace std;
struct Student {
int id;
int totalScore{0};
unordered_map<int, int> grades;
};
struct Assignment {
int id;
};
class Course {
private:
unordered_map<int, Student> stds;
unordered_map<int, Assignment> asgns;
public:
Course() {}
void addAssignment(int aId) {
if (asgns.count(aId)) {
cout << "Assignment " << aId << " already exists." << endl;
return;
}
asgns.emplace(aId, Assignment{aId});
}
void enrollStudent(int sId) {
if (stds.count(sId)) {
cout << "Student " << sId << " is already enrolled." << endl;
return;
}
stds.emplace(sId, Student{sId});
}
void addStudentGrade(int sId, int aId, int grd) {
if (!stds.count(sId)) {
cout << "Student " << sId << " is not enrolled." << endl;
return;
}
if (!asgns.count(aId)) {
cout << "Assignment " << aId << " does not exist." << endl;
return;
}
auto& std = stds.at(sId);
if (std.grades.count(aId)) {
std.totalScore -= std.grades[aId];
}
std.totalScore += grd;
std.grades[aId] = grd;
}
float getStudentGrade(int sId) {
if (!stds.count(sId)) {
cout << "Student " << sId << " is not enrolled." << endl;
return -1.0f;
}
auto& std = stds.at(sId);
if (std.grades.empty()) {
cout << "No grades available for student " << sId << "." << endl;
return -1.0f;
}
return static_cast<float>(std.totalScore) / std.grades.size();
}
void unenrollStudent(int sId) {
if (stds.count(sId)) {
stds.erase(sId);
}
}
float getOverallAssignmentGrade(int aId) {
if (!asgns.count(aId)) {
cout << "Assignment " << aId << " does not exist." << endl;
return -1.0f;
}
int total = 0;
int count = 0;
for (auto const& [sId, std] : stds) {
if (std.grades.count(aId)) {
total += std.grades.at(aId);
count++;
}
}
if (count == 0) {
cout << "No grades submitted for assignment " << aId << "." << endl;
return -1.0f;
}
return static_cast<float>(total) / count;
}
vector<int> getUninvolvedStudents() {
vector<int> result;
size_t threshold = asgns.size() / 2;
for (auto const& [sId, std] : stds) {
if (std.grades.size() <= threshold) {
result.push_back(sId);
}
}
return result;
}
int getStudentWorstAssignment(int sId) {
if (!stds.count(sId)) {
cout << "Student " << sId << " not found." << endl;
return -1;
}
auto& std = stds.at(sId);
if (std.grades.empty()) {
cout << "No grades for student " << sId << "." << endl;
return -1;
}
int worstAsgnId = -1;
int minGrade = INT_MAX;
for (auto const& [aId, grd] : std.grades) {
if (grd < minGrade) {
minGrade = grd;
worstAsgnId = aId;
}
}
return worstAsgnId;
}
vector<int> getTopStudents() {
vector<pair<float, int>> studentAvgs;
for (auto const& [sId, std] : stds) {
if (!std.grades.empty()) {
float avg = static_cast<float>(std.totalScore) / std.grades.size();
studentAvgs.push_back({avg, sId});
}
}
sort(studentAvgs.rbegin(), studentAvgs.rend());
vector<int> topStudents;
int count = 0;
for(const auto& p : studentAvgs) {
if (count++ < 3) {
topStudents.push_back(p.second);
} else {
break;
}
}
return topStudents;
}
};
int main() {
Course course;
cout << "--- Initial Setup ---" << endl;
course.enrollStudent(101);
course.enrollStudent(102);
course.enrollStudent(103);
course.enrollStudent(104);
course.enrollStudent(101);
course.addAssignment(1);
course.addAssignment(2);
course.addAssignment(3);
course.addAssignment(4);
course.addAssignment(1);
cout << "\n--- Adding Grades ---" << endl;
course.addStudentGrade(101, 1, 90);
course.addStudentGrade(101, 2, 80);
course.addStudentGrade(102, 1, 100);
course.addStudentGrade(102, 2, 95);
course.addStudentGrade(102, 3, 98);
course.addStudentGrade(103, 1, 85);
course.addStudentGrade(103, 2, 88);
course.addStudentGrade(103, 4, 70);
course.addStudentGrade(105, 1, 90);
course.addStudentGrade(101, 5, 90);
cout << "\n--- Calculating Averages ---" << endl;
cout << "Student 101 Average: " << course.getStudentGrade(101) << endl;
cout << "Student 102 Average: " << course.getStudentGrade(102) << endl;
cout << "Student 104 Average: " << course.getStudentGrade(104) << endl;
cout << "\n--- Part 2 Function Tests ---" << endl;
cout << "\nOverall grade for Assignment 1: " << course.getOverallAssignmentGrade(1) << endl;
cout << "Overall grade for Assignment 3: " << course.getOverallAssignmentGrade(3) << endl;
cout << "\nStudent 102's worst assignment: " << course.getStudentWorstAssignment(102) << endl;
cout << "Student 103's worst assignment: " << course.getStudentWorstAssignment(103) << endl;
cout << "\nUninvolved students: ";
vector<int> uninvolved = course.getUninvolvedStudents();
for(int id : uninvolved) cout << id << " ";
cout << endl;
cout << "\nUnenrolling student 103..." << endl;
course.unenrollStudent(103);
cout << "Trying to get Student 103 Average: " << course.getStudentGrade(103) << endl;
cout << "\nTop students: ";
vector<int> top = course.getTopStudents();
for(int id : top) cout << id << " ";
cout << endl;
return 0;
}