Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <filesystem>
- #include <fstream>
- #include <string>
- #include <sstream>
- #include <locale>
- #include <cmath>
- #include <cctype>
- #include <exception>
- using namespace std;
- struct TaskParams
- {
- int numOfSheets;
- int firstPrintingTime;
- int secondPrintingTime;
- int firstPrinterFailureRate;
- float firstPrinterFailureProbability;
- int firstPrinterRepairTime;
- int secondPrinterFailureRate;
- float secondPrinterFailureProbability;
- int secondPrinterRepairTime;
- };
- class InvalidValueException : public std::exception {
- public:
- InvalidValueException(const std::string& message) : m_message(message) {}
- const char* what() const noexcept override {
- return m_message.c_str();
- }
- private:
- std::string m_message;
- };
- class InvalidInputFileException : public std::exception {
- public:
- InvalidInputFileException(const std::string& message) : m_message(message) {}
- const char* what() const noexcept override {
- return m_message.c_str();
- }
- private:
- std::string m_message;
- };
- int calcMinPrintingTime(TaskParams params)
- {
- // Считаем, что первый принтер самый быстрый
- if (params.firstPrintingTime > params.secondPrintingTime)
- {
- swap(params.firstPrintingTime, params.secondPrintingTime);
- swap(params.firstPrinterFailureRate, params.secondPrinterFailureRate);
- swap(params.firstPrinterFailureProbability, params.secondPrinterFailureProbability);
- swap(params.firstPrinterRepairTime, params.secondPrinterRepairTime);
- }
- int minimumPrintingTime = 0;
- // Печатаем первую страницу на самом быстром принтере
- params.numOfSheets = params.numOfSheets - 1;
- minimumPrintingTime += params.firstPrintingTime;
- // Определяем таймеры времени для отсчета на печать 1 страницы
- int firstPrintingTimer = 0, secondPrintintTimer = 0;
- // Определяем общее время безотказной работы принтеров
- int firstPrintrerStableOpTime = minimumPrintingTime;
- int secondPrintrerStableOpTime = 0;
- // Проверяем, работоспособен ли первый принтер после печати первой страницы
- if (firstPrintrerStableOpTime >= params.firstPrinterFailureRate &&
- (float)rand() / RAND_MAX <= params.firstPrinterFailureProbability)
- {
- // Если принтер сломан, то сбрасываем таймер печати и общее время безотказной работы,
- // на время, требующееся на восстановление работы принтера
- firstPrintingTimer = firstPrintrerStableOpTime = -params.firstPrinterRepairTime;
- }
- // Пока не распечатали все страницы
- while (params.numOfSheets > 0)
- {
- minimumPrintingTime++; firstPrintingTimer++; secondPrintintTimer++;
- firstPrintrerStableOpTime++; secondPrintrerStableOpTime++;
- // Проевряем работоспособность принтеров, после каждой секунды печати
- if (firstPrintrerStableOpTime >= params.firstPrinterFailureRate &&
- (float)rand() / RAND_MAX <= params.firstPrinterFailureProbability)
- {
- firstPrintingTimer = firstPrintrerStableOpTime = -params.firstPrinterRepairTime;
- }
- if (secondPrintrerStableOpTime >= params.secondPrinterFailureRate &&
- (float)rand() / RAND_MAX <= params.secondPrinterFailureProbability)
- {
- secondPrintintTimer = secondPrintrerStableOpTime = -params.secondPrinterRepairTime;
- }
- // Если прошло нужное время на печать одной страницы, то считаем, что страницу распечатали
- if (firstPrintingTimer == params.firstPrintingTime)
- {
- params.numOfSheets--;
- firstPrintingTimer = 0;
- }
- if (secondPrintintTimer == params.secondPrintingTime)
- {
- params.numOfSheets--;
- secondPrintintTimer = 0;
- }
- }
- return minimumPrintingTime;
- }
- int countValuesInLine(const std::string& input_line) {
- std::istringstream iss(input_line);
- int count = 0;
- while (iss.good()) {
- std::string value;
- iss >> value;
- if (!value.empty()) ++count;
- }
- return count;
- }
- bool readInputFile(std::ifstream& input_file, TaskParams* params)
- {
- string input_line;
- if (std::getline(input_file, input_line)) {
- std::istringstream iss(input_line);
- iss >> params->numOfSheets
- >> params->firstPrintingTime
- >> params->secondPrintingTime
- >> params->firstPrinterFailureRate
- >> params->firstPrinterFailureProbability
- >> params->firstPrinterRepairTime
- >> params->secondPrinterFailureRate
- >> params->secondPrinterFailureProbability
- >> params->secondPrinterRepairTime;
- if (countValuesInLine(input_line) != 9)
- {
- // Ошибка чтения параметров
- throw InvalidInputFileException("Во входной строке неверное количество параметров. "
- "Убедитесь, что введены 9 параметров, разделенных пробелами.\n");
- }
- if (iss.fail())
- {
- throw InvalidInputFileException("Во входной строке один из параметров не является числом. "
- "Убедитесь, что были введены 9 параметров в числовом формате, разделенных пробелами.\n");
- }
- }
- else {
- // Ошибка чтения строки из файла
- throw InvalidInputFileException("Во входной строке неверное количество параметров. "
- "Убедитесь, что введены 9 параметров, разделенных пробелами.\n");
- }
- if (std::getline(input_file, input_line))
- {
- throw InvalidInputFileException("Программа принимает на вход файлы из одной строки. "
- "Разместите все параметры в одной строке.");
- }
- return true;
- }
- bool isInRange(float value, float left_border, float right_border)
- {
- return left_border <= value && value <= right_border;
- }
- bool validateInputData(const TaskParams params) throw (char*)
- {
- if (!isInRange(params.numOfSheets, 1, 2 * pow(10, 8)))
- throw InvalidValueException("Параметр N не принадлежит диапазону [1..2 ∙〖10〗^8].\n");
- if (!isInRange(params.firstPrintingTime, 1, 10))
- throw InvalidValueException("Параметр X не принадлежит диапазону [1..10].\n");
- if (!isInRange(params.secondPrintingTime, 1, 10))
- throw InvalidValueException("Параметр Y не принадлежит диапазону [1..10].\n");
- if (!isInRange(params.firstPrinterFailureRate, 1, 10))
- throw InvalidValueException("Параметр L1 не принадлежит диапазону [1..10].\n");
- if (!isInRange(params.secondPrinterFailureRate, 1, 10))
- throw InvalidValueException("Параметр L2 не принадлежит диапазону [1..10].\n");
- if (!isInRange(params.firstPrinterFailureProbability, 0.01, 0.99))
- throw InvalidValueException("Параметр P1 не принадлежит диапазону [0.01..0.99].\n");
- if (!isInRange(params.secondPrinterFailureProbability, 0.01, 0.99))
- throw InvalidValueException("Параметр P2 не принадлежит диапазону [0.01..0.99].\n");
- if (!isInRange(params.firstPrinterRepairTime, 0, 10))
- throw InvalidValueException("Параметр K1 не принадлежит диапазону [0..10].\n");
- if (!isInRange(params.secondPrinterRepairTime, 0, 10))
- throw InvalidValueException("Параметр K2 не принадлежит диапазону [0..10].\n");
- return true;
- }
- int main(int argc, char* argv[])
- {
- setlocale(LC_ALL, "Russian");
- if (argc != 3)
- {
- std::cerr << "Usage: " << argv[0] << " <path/to/input_file> <path/to/save_file>\n";
- return 1;
- }
- std::ifstream input_file(argv[1]);
- if (!input_file.is_open()) {
- std::cerr << "Неверно указан файл с входными данными. Возможно, файл не существует." << argv[1] << '\n';
- return 1;
- }
- filesystem::path output_path = filesystem::path(argv[2]);
- if (!(filesystem::exists(output_path.parent_path()) &&
- filesystem::is_directory(output_path.parent_path()) &&
- output_path.has_filename()))
- {
- std::cerr << "Неверно указан файл для выходных данных. "
- "Возможно указанного расположения не существует или нет прав на запись." << '\n';
- return 1;
- }
- std::ofstream output_file(output_path);
- if (!output_file.is_open()) {
- std::cerr << "Неверно указан файл для выходных данных. "
- "Возможно указанного расположения не существует или нет прав на запись." << '\n';
- return 1;
- }
- TaskParams params = {};
- try {
- readInputFile(input_file, ¶ms);
- validateInputData(params);
- } catch (const InvalidValueException& e) {
- output_file << e.what();
- return 1;
- } catch (const InvalidInputFileException& e) {
- output_file << e.what();
- return 1;
- }
- output_file << calcMinPrintingTime(params);
- // Закрыть файлы
- input_file.close();
- output_file.close();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement