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
44 changes: 44 additions & 0 deletions lab2/Functions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "Functions.h"

std::vector<QuadraticEquation> readEquationsFromFile(const std::string& filename) {
std::ifstream file(filename);
std::vector<QuadraticEquation> equations;

if (!file.is_open()) {
std::cerr << "Ошибка: не удалось открыть файл " << filename << "\n";
return equations;
}

double a, b, c;
while (file >> a >> b >> c) {
equations.emplace_back(a, b, c);
}

if (equations.empty()) {
std::cerr << "Предупреждение: файл не содержит уравнений\n";
}

file.close();
return equations;
}

double discriminant(double k[]) {
return (k[1] * k[1]) - (4 * k[0] * k[2]);
}

double* solve(double k[], double res[]) {
double dis = discriminant(k);

if (dis < 0) {
res[0] = res[1] = 0.0;
}
else if (dis == 0) {
res[0] = res[1] = (-k[1]) / (2 * k[0]);
}
else {
double sqrt_dis = sqrt(dis);
res[0] = (-k[1] + sqrt_dis) / (2 * k[0]);
res[1] = (-k[1] - sqrt_dis) / (2 * k[0]);
}
return res;
}
36 changes: 36 additions & 0 deletions lab2/Functions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once
#include <iostream>
#include <fstream>
#include <locale.h>
#include <vector>
#include <string>

struct QuadraticEquation {
double a, b, c;

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

std::string toString() const {
return std::to_string(a) + "x^2 + " + std::to_string(b) + "x + " + std::to_string(c) + " = 0";
}

void getCoefficients(double k[3]) const {
k[0] = a;
k[1] = b;
k[2] = c;
}
};

struct EquationSolution {
int num_roots;
double root1, root2;
std::string student_name;

EquationSolution(int nr = 0, double r1 = 0, double r2 = 0, std::string name = "")
: num_roots(nr), root1(r1), root2(r2), student_name(name) {
}
};

std::vector<QuadraticEquation> readEquationsFromFile(const std::string& filename);
double discriminant(double[]);
double* solve(double[], double[]);
35 changes: 35 additions & 0 deletions lab2/Main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "Functions.h"
#include "Objects.cpp"

int main() {
srand(time(0));
setlocale(LC_ALL, "Russian");

std::vector<std::unique_ptr<Student>> students;
students.emplace_back(std::make_unique<GoodStudent>("Иван Иванов (отличник)"));
students.emplace_back(std::make_unique<AverageStudent>("Петр Петров (середнячок)"));
students.emplace_back(std::make_unique<AverageStudent>("Николай Николаев (середнячок)"));
students.emplace_back(std::make_unique<BadStudent>("Сергей Сергеев (двоечник)"));

auto equations = readEquationsFromFile("equations.txt");
if (equations.empty()) {
std::cout << "Используем уравнения по умолчанию...\n";
equations = {
{1, 2, 1},
{1, 0, 1},
{1, -4, 3},
};
}

Teacher teacher;
for (const auto& eq : equations) {
for (const auto& student : students) {
auto solution = student->solveEquation(eq);
teacher.addSubmission(eq, solution);
}
}

teacher.gradeAllSubmissions(students);
teacher.publishResults();
return 0;
}
148 changes: 148 additions & 0 deletions lab2/Objects.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#include "Functions.h"
#include <map>
#include <ctime>
#include <iomanip>

class Student {
protected:
std::string name;

public:
Student(const std::string& name) : name(name) {}
virtual ~Student() = default;
virtual EquationSolution solveEquation(const QuadraticEquation& eq) = 0;
std::string getName() const { return name; }
};

class GoodStudent : public Student {
public:
GoodStudent(const std::string& name) : Student(name) {}

EquationSolution solveEquation(const QuadraticEquation& eq) override {
double k[3];
eq.getCoefficients(k);
double res[2];
solve(k, res);
double dis = discriminant(k);

if (dis < 0) {
return EquationSolution(0, 0, 0, name);
}
else if (dis == 0) {
return EquationSolution(1, res[0], 0, name);
}
else {
return EquationSolution(2, res[0], res[1], name);
}
}
};

class AverageStudent : public Student {
public:
AverageStudent(const std::string& name) : Student(name) {}

EquationSolution solveEquation(const QuadraticEquation& eq) override {
if ((rand() % 100) < 60) { // 60%
double k[3];
eq.getCoefficients(k);
double res[2];
solve(k, res);
double dis = discriminant(k);

if (dis < 0) {
return EquationSolution(0, 0, 0, name);
}
else if (dis == 0) {
return EquationSolution(1, res[0], 0, name);
}
else {
return EquationSolution(2, res[0], res[1], name);
}
}
else {
int num_roots = rand() % 3;
double root1 = (rand() % 100)/10.0;
double root2 = 0;
if (num_roots == 2) {
root2 = (rand() % 100)/10.0;
}
else {
root2 = 0;
}
return EquationSolution(num_roots, root1, root2, name);
}
}
};

class BadStudent : public Student {
public:
BadStudent(const std::string& name) : Student(name) {}

EquationSolution solveEquation(const QuadraticEquation& eq) override {
return EquationSolution(1, 0, 0, name);
}
};

class Teacher {
private:
std::vector<std::pair<QuadraticEquation, EquationSolution>> submissions;
std::map<std::string, int> results;

public:
bool checkSolution(const QuadraticEquation& eq, const EquationSolution& sol) {
double k[3];
eq.getCoefficients(k);
double correct_res[2];
solve(k, correct_res);
double dis = discriminant(k);

if (dis < 0) {
return sol.num_roots == 0;
}
else if (dis == 0) {
if (sol.num_roots != 1) return false;
return std::abs(correct_res[0] - sol.root1) < 1e-6;
}
else {
if (sol.num_roots != 2) return false;

bool match1 = (std::abs(correct_res[0] - sol.root1) < 1e-6 &&
std::abs(correct_res[1] - sol.root2) < 1e-6);
bool match2 = (std::abs(correct_res[0] - sol.root2) < 1e-6 &&
std::abs(correct_res[1] - sol.root1) < 1e-6);

return match1 || match2;
}
}

void addSubmission(const QuadraticEquation& eq, const EquationSolution& sol) {
submissions.emplace_back(eq, sol);
}

void gradeAllSubmissions(const std::vector<std::unique_ptr<Student>>& students) {

for (const auto& student : students) {
results[student->getName()] = 0;
}
for (const auto& submission : submissions) {
const auto& eq = submission.first;
const auto& sol = submission.second;

if (checkSolution(eq, sol)) {
results[sol.student_name]++;
}
}
}

void publishResults() const {
setlocale(LC_ALL, "Russian");
std::cout << "=== Результаты зачета ===\n";
std::cout << std::setw(25) << std::left << "Студент" << "Решено задач\n";
std::cout << "---------------------------\n";

for (const auto& entry : results) {
std::cout << std::setw(25) << std::left << entry.first
<< entry.second << std::endl;
}
}
};
3 changes: 3 additions & 0 deletions lab2/equations.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1 2 4
1 6 9
2 8 8