Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)

set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)

project(avto_kvadrat CXX)

################################################################################
# Set target arch type if empty. Visual studio solution generator provides it.
################################################################################
if(NOT CMAKE_VS_PLATFORM_NAME)
set(CMAKE_VS_PLATFORM_NAME "x64")
endif()
message("${CMAKE_VS_PLATFORM_NAME} architecture in use")

if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64"
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86"))
message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!")
endif()

################################################################################
# Global configuration types
################################################################################
set(CMAKE_CONFIGURATION_TYPES
"Debug"
"Release"
CACHE STRING "" FORCE
)

################################################################################
# Global compiler options
################################################################################
if(MSVC)
# remove default flags provided with CMake for MSVC
set(CMAKE_CXX_FLAGS "")
set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_RELEASE "")
endif()

################################################################################
# Global linker options
################################################################################
if(MSVC)
# remove default flags provided with CMake for MSVC
set(CMAKE_EXE_LINKER_FLAGS "")
set(CMAKE_MODULE_LINKER_FLAGS "")
set(CMAKE_SHARED_LINKER_FLAGS "")
set(CMAKE_STATIC_LINKER_FLAGS "")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "${CMAKE_STATIC_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS}")
endif()

################################################################################
# Nuget packages function stub.
################################################################################
function(use_package TARGET PACKAGE VERSION)
message(WARNING "No implementation of use_package. Create yours. "
"Package \"${PACKAGE}\" with version \"${VERSION}\" "
"for target \"${TARGET}\" is ignored!")
endfunction()

################################################################################
# Common utils
################################################################################
include(CMake/Utils.cmake)

################################################################################
# Additional Global Settings(add specific info there)
################################################################################
include(CMake/GlobalSettingsInclude.cmake OPTIONAL)

################################################################################
# Use solution folders feature
################################################################################
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

################################################################################
# Sub-projects
################################################################################
add_subdirectory(avto_kvadrat)

9 changes: 9 additions & 0 deletions EmailQueue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "EmailQueue.h"

void EmailQueue::addEmail(const QuadraticEquation& eq, const std::vector<double>& solution, const std::string& studentName) {
emails.push(std::make_tuple(eq, solution, studentName));
}

std::queue<std::tuple<QuadraticEquation, std::vector<double>, std::string>> EmailQueue::getEmails() const {
return emails;
}
17 changes: 17 additions & 0 deletions EmailQueue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef EMAIL_QUEUE_H
#define EMAIL_QUEUE_H

#include "QuadraticEquation.h"
#include <queue>
#include <tuple>
#include <string>

class EmailQueue {
private:
std::queue<std::tuple<QuadraticEquation, std::vector<double>, std::string>> emails;
public:
void addEmail(const QuadraticEquation& eq, const std::vector<double>& solution, const std::string& studentName);
std::queue<std::tuple<QuadraticEquation, std::vector<double>, std::string>> getEmails() const;
};

#endif
81 changes: 81 additions & 0 deletions Instructor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include "Instructor.h"
#include <iostream>
#include <cmath>
#include <iomanip>
#include <fstream>
#include <vector>
#include <algorithm>


void Instructor::initializeStudents(const EmailQueue& queue) {
auto emails = queue.getEmails();
while (!emails.empty()) {
const auto& email = emails.front();
const std::string& studentName = std::get<2>(email);
allStudents.insert(studentName);
emails.pop();
}
for (const auto& name : allStudents) {
results[name] = 0;
}
}

bool compareSolutions(const std::vector<double>& correct, const std::vector<double>& student) {
if (correct.size() != student.size()) return false;
for (size_t i = 0; i < correct.size(); ++i) {
if (std::abs(correct[i] - student[i]) > 1e-6) return false;
}
return true;
}

void Instructor::checkEmails(const EmailQueue& queue) {
initializeStudents(queue);

auto emails = queue.getEmails();
while (!emails.empty()) {
const auto& email = emails.front();
const QuadraticEquation& eq = std::get<0>(email);
const std::vector<double>& studentSolution = std::get<1>(email);
const std::string& studentName = std::get<2>(email);

auto correctSolution = eq.solve();
if (compareSolutions(correctSolution, studentSolution)) {
results[studentName]++;
}
emails.pop();
}
}

void Instructor::publishResults(const std::string& filename) const {
if (results.empty()) {
std::cout << "No results to publish.\n";
return;
}

std::vector<std::pair<std::string, int>> sortedResults(results.begin(), results.end());
std::sort(sortedResults.begin(), sortedResults.end(),
[](const auto& a, const auto& b) { return a.second > b.second; });

auto printTable = [&](std::ostream& os) {
os << std::setw(20) << "Student Name" << " | " << std::setw(6) << "Correct" << "\n";
os << "----------------------+--------\n";
for (const auto& pair : sortedResults) {
os << std::setw(20) << pair.first << " | " << std::setw(6) << pair.second << "\n";
}
};

if (!filename.empty()) {
std::ofstream file(filename);
if (file.is_open()) {
printTable(file);
file.close();
std::cout << "Results saved to " << filename << std::endl;
}
else {
std::cerr << "Error: Unable to open file for writing." << std::endl;
}
}
else {
printTable(std::cout);
}
}
21 changes: 21 additions & 0 deletions Instructor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef INSTRUCTOR_H
#define INSTRUCTOR_H

#include "EmailQueue.h"
#include <map>
#include <set>
#include <string>

class Instructor {
private:
std::map<std::string, int> results;
std::set<std::string> allStudents;

void initializeStudents(const EmailQueue& queue);

public:
void checkEmails(const EmailQueue& queue);
void publishResults(const std::string& filename = "") const;
};

#endif
25 changes: 25 additions & 0 deletions QuadraticEquation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "QuadraticEquation.h"
#include <cmath>
#include <algorithm>

QuadraticEquation::QuadraticEquation(double a, double b, double c) : a(a), b(b), c(c) {}

std::vector<double> QuadraticEquation::solve() const {
std::vector<double> roots;
if (a == 0) {
if (b == 0) return roots;
roots.push_back(-c / b);
return roots;
}
double discriminant = b * b - 4 * a * c;
if (discriminant > 0) {
double sqrtD = std::sqrt(discriminant);
roots.push_back((-b + sqrtD) / (2 * a));
roots.push_back((-b - sqrtD) / (2 * a));
std::sort(roots.begin(), roots.end());
}
else if (discriminant == 0) {
roots.push_back(-b / (2 * a));
}
return roots;
}
14 changes: 14 additions & 0 deletions QuadraticEquation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef QUADRATIC_EQUATION_H
#define QUADRATIC_EQUATION_H

#include <vector>

class QuadraticEquation {
private:
double a, b, c;
public:
QuadraticEquation(double a, double b, double c);
std::vector<double> solve() const;
};

#endif
30 changes: 30 additions & 0 deletions Student.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "Student.h"
#include <cstdlib>
#include <ctime>
#include <cmath>

std::vector<double> GoodStudent::solve(const QuadraticEquation& eq) const {
return eq.solve();
}

std::vector<double> AverageStudent::solve(const QuadraticEquation& eq) const {
if (static_cast<double>(rand()) / RAND_MAX < probability) {
return eq.solve();
}
else {
std::vector<double> wrong = eq.solve();
if (!wrong.empty()) {
for (double& root : wrong) {
root += (static_cast<double>(rand()) / RAND_MAX - 0.5) * 2;
}
}
else {
wrong.push_back(0);
}
return wrong;
}
}

std::vector<double> BadStudent::solve(const QuadraticEquation& eq) const {
return { 0 };
}
38 changes: 38 additions & 0 deletions Student.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef STUDENT_H
#define STUDENT_H

#include "QuadraticEquation.h"
#include <vector>
#include <string>

class Student {
protected:
std::string name;
public:
Student(const std::string& name) : name(name) {}
virtual std::vector<double> solve(const QuadraticEquation& eq) const = 0;
std::string getName() const { return name; }
virtual ~Student() = default;
};

class GoodStudent : public Student {
public:
GoodStudent(const std::string& name) : Student(name) {}
std::vector<double> solve(const QuadraticEquation& eq) const override;
};

class AverageStudent : public Student {
private:
double probability;
public:
AverageStudent(const std::string& name, double prob) : Student(name), probability(prob) {}
std::vector<double> solve(const QuadraticEquation& eq) const override;
};

class BadStudent : public Student {
public:
BadStudent(const std::string& name) : Student(name) {}
std::vector<double> solve(const QuadraticEquation& eq) const override;
};

#endif
4 changes: 4 additions & 0 deletions equations.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1 0 -4
0 2 -8
1 2 1
1 1 1
47 changes: 47 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "QuadraticEquation.h"
#include "Student.h"
#include "EmailQueue.h"
#include "Instructor.h"
#include <fstream>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <ctime>

std::vector<QuadraticEquation> readEquations(const std::string& filename) {
std::vector<QuadraticEquation> equations;
std::ifstream file(filename);
std::string line;
while (std::getline(file, line)) {
std::istringstream iss(line);
double a, b, c;
if (iss >> a >> b >> c) {
equations.emplace_back(a, b, c);
}
}
return equations;
}

int main() {
srand(42);

auto equations = readEquations("equations.txt");

GoodStudent good("Alice");
AverageStudent average("Bob", 0.5);
BadStudent bad("Charlie");

EmailQueue queue;

for (const auto& eq : equations) {
queue.addEmail(eq, good.solve(eq), good.getName());
queue.addEmail(eq, average.solve(eq), average.getName());
queue.addEmail(eq, bad.solve(eq), bad.getName());
}

Instructor instructor;
instructor.checkEmails(queue);
instructor.publishResults();

return 0;
}