Advertisement
gg-master

KINPO

Apr 8th, 2023
426
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.45 KB | None | 0 0
  1. #include <iostream>
  2. #include <filesystem>
  3. #include <fstream>
  4. #include <string>
  5. #include <sstream>
  6. #include <locale>
  7. #include <cmath>
  8. #include <cctype>
  9. #include <exception>
  10.  
  11.  
  12. using namespace std;
  13.  
  14.  
  15. struct TaskParams
  16. {
  17.     int numOfSheets;
  18.     int firstPrintingTime;
  19.     int secondPrintingTime;
  20.  
  21.     int firstPrinterFailureRate;
  22.     float firstPrinterFailureProbability;
  23.     int firstPrinterRepairTime;
  24.  
  25.     int secondPrinterFailureRate;
  26.     float secondPrinterFailureProbability;
  27.     int secondPrinterRepairTime;
  28. };
  29.  
  30.  
  31. class InvalidValueException : public std::exception {
  32. public:
  33.     InvalidValueException(const std::string& message) : m_message(message) {}
  34.  
  35.     const char* what() const noexcept override {
  36.         return m_message.c_str();
  37.     }
  38. private:
  39.     std::string m_message;
  40. };
  41.  
  42. class InvalidInputFileException : public std::exception {
  43. public:
  44.     InvalidInputFileException(const std::string& message) : m_message(message) {}
  45.  
  46.     const char* what() const noexcept override {
  47.         return m_message.c_str();
  48.     }
  49. private:
  50.     std::string m_message;
  51. };
  52.  
  53.  
  54. int calcMinPrintingTime(TaskParams params)
  55. {
  56.  
  57.     // Считаем, что первый принтер самый быстрый
  58.     if (params.firstPrintingTime > params.secondPrintingTime)
  59.     {
  60.         swap(params.firstPrintingTime, params.secondPrintingTime);
  61.         swap(params.firstPrinterFailureRate, params.secondPrinterFailureRate);
  62.         swap(params.firstPrinterFailureProbability, params.secondPrinterFailureProbability);
  63.         swap(params.firstPrinterRepairTime, params.secondPrinterRepairTime);
  64.     }
  65.  
  66.     int minimumPrintingTime = 0;
  67.  
  68.     // Печатаем первую страницу на самом быстром принтере
  69.     params.numOfSheets = params.numOfSheets - 1;
  70.     minimumPrintingTime += params.firstPrintingTime;
  71.  
  72.     // Определяем таймеры времени для отсчета на печать 1 страницы
  73.     int firstPrintingTimer = 0, secondPrintintTimer = 0;  
  74.  
  75.     // Определяем общее время безотказной работы принтеров
  76.     int firstPrintrerStableOpTime = minimumPrintingTime;
  77.     int secondPrintrerStableOpTime = 0;
  78.  
  79.     // Проверяем, работоспособен ли первый принтер после печати первой страницы
  80.     if (firstPrintrerStableOpTime >= params.firstPrinterFailureRate &&
  81.         (float)rand() / RAND_MAX <= params.firstPrinterFailureProbability)
  82.     {
  83.         // Если принтер сломан, то сбрасываем таймер печати и общее время безотказной работы,
  84.         // на время, требующееся на восстановление работы принтера
  85.         firstPrintingTimer = firstPrintrerStableOpTime = -params.firstPrinterRepairTime;
  86.     }
  87.  
  88.     // Пока не распечатали все страницы
  89.     while (params.numOfSheets > 0)
  90.     {
  91.         minimumPrintingTime++; firstPrintingTimer++; secondPrintintTimer++;
  92.         firstPrintrerStableOpTime++; secondPrintrerStableOpTime++;
  93.  
  94.         // Проевряем работоспособность принтеров, после каждой секунды печати
  95.         if (firstPrintrerStableOpTime >= params.firstPrinterFailureRate &&
  96.             (float)rand() / RAND_MAX <= params.firstPrinterFailureProbability)
  97.         {
  98.             firstPrintingTimer = firstPrintrerStableOpTime = -params.firstPrinterRepairTime;
  99.         }
  100.         if (secondPrintrerStableOpTime >= params.secondPrinterFailureRate &&
  101.             (float)rand() / RAND_MAX <= params.secondPrinterFailureProbability)
  102.         {
  103.             secondPrintintTimer = secondPrintrerStableOpTime = -params.secondPrinterRepairTime;
  104.         }
  105.  
  106.         // Если прошло нужное время на печать одной страницы, то считаем, что страницу распечатали
  107.         if (firstPrintingTimer == params.firstPrintingTime)
  108.         {
  109.             params.numOfSheets--;
  110.             firstPrintingTimer = 0;
  111.         }
  112.         if (secondPrintintTimer == params.secondPrintingTime)
  113.         {
  114.             params.numOfSheets--;
  115.             secondPrintintTimer = 0;
  116.         }
  117.     }
  118.     return minimumPrintingTime;
  119. }
  120.  
  121.  
  122. int countValuesInLine(const std::string& input_line) {
  123.     std::istringstream iss(input_line);
  124.     int count = 0;
  125.     while (iss.good()) {
  126.         std::string value;
  127.         iss >> value;
  128.         if (!value.empty()) ++count;
  129.     }
  130.     return count;
  131. }
  132.  
  133.  
  134. bool readInputFile(std::ifstream& input_file, TaskParams* params)
  135. {
  136.  
  137.     string input_line;
  138.     if (std::getline(input_file, input_line)) {
  139.         std::istringstream iss(input_line);
  140.  
  141.         iss >> params->numOfSheets
  142.             >> params->firstPrintingTime
  143.             >> params->secondPrintingTime
  144.             >> params->firstPrinterFailureRate
  145.             >> params->firstPrinterFailureProbability
  146.             >> params->firstPrinterRepairTime
  147.             >> params->secondPrinterFailureRate
  148.             >> params->secondPrinterFailureProbability
  149.             >> params->secondPrinterRepairTime;
  150.  
  151.         if (countValuesInLine(input_line) != 9)
  152.         {
  153.             // Ошибка чтения параметров
  154.             throw InvalidInputFileException("Во входной строке неверное количество параметров. "
  155.                 "Убедитесь, что введены 9 параметров, разделенных пробелами.\n");
  156.         }
  157.         if (iss.fail())
  158.         {  
  159.             throw InvalidInputFileException("Во входной строке один из параметров не является числом. "
  160.                 "Убедитесь, что были введены 9 параметров в числовом формате, разделенных пробелами.\n");
  161.         }
  162.     }
  163.     else {
  164.         // Ошибка чтения строки из файла
  165.         throw InvalidInputFileException("Во входной строке неверное количество параметров. "
  166.             "Убедитесь, что введены 9 параметров, разделенных пробелами.\n");
  167.     }
  168.     if (std::getline(input_file, input_line))
  169.     {
  170.         throw InvalidInputFileException("Программа принимает на вход файлы из одной строки. "
  171.             "Разместите все параметры в одной строке.");
  172.     }
  173.     return true;
  174. }
  175.  
  176.  
  177. bool isInRange(float value, float left_border, float right_border)
  178. {
  179.     return left_border <= value && value <= right_border;
  180. }
  181.  
  182.  
  183. bool validateInputData(const TaskParams params) throw (char*)
  184. {
  185.     if (!isInRange(params.numOfSheets, 1, 2 * pow(10, 8)))
  186.         throw InvalidValueException("Параметр N не принадлежит диапазону [1..2 ∙〖10〗^8].\n");
  187.  
  188.     if (!isInRange(params.firstPrintingTime, 1, 10))
  189.         throw InvalidValueException("Параметр X не принадлежит диапазону [1..10].\n");
  190.  
  191.     if (!isInRange(params.secondPrintingTime, 1, 10))
  192.         throw InvalidValueException("Параметр Y не принадлежит диапазону [1..10].\n");
  193.  
  194.     if (!isInRange(params.firstPrinterFailureRate, 1, 10))
  195.         throw InvalidValueException("Параметр L1 не принадлежит диапазону [1..10].\n");
  196.    
  197.     if (!isInRange(params.secondPrinterFailureRate, 1, 10))
  198.         throw InvalidValueException("Параметр L2 не принадлежит диапазону [1..10].\n");
  199.  
  200.     if (!isInRange(params.firstPrinterFailureProbability, 0.01, 0.99))
  201.         throw InvalidValueException("Параметр P1 не принадлежит диапазону [0.01..0.99].\n");
  202.  
  203.     if (!isInRange(params.secondPrinterFailureProbability, 0.01, 0.99))
  204.         throw InvalidValueException("Параметр P2 не принадлежит диапазону [0.01..0.99].\n");
  205.  
  206.     if (!isInRange(params.firstPrinterRepairTime, 0, 10))
  207.         throw InvalidValueException("Параметр K1 не принадлежит диапазону [0..10].\n");
  208.  
  209.     if (!isInRange(params.secondPrinterRepairTime, 0, 10))
  210.         throw InvalidValueException("Параметр K2 не принадлежит диапазону [0..10].\n");
  211.    
  212.     return true;
  213. }
  214.  
  215.  
  216. int main(int argc, char* argv[])
  217. {
  218.     setlocale(LC_ALL, "Russian");
  219.     if (argc != 3)
  220.     {
  221.         std::cerr << "Usage: " << argv[0] << " <path/to/input_file> <path/to/save_file>\n";
  222.         return 1;
  223.     }
  224.    
  225.     std::ifstream input_file(argv[1]);
  226.  
  227.     if (!input_file.is_open()) {
  228.         std::cerr << "Неверно указан файл с входными данными. Возможно, файл не существует." << argv[1] << '\n';
  229.         return 1;
  230.     }
  231.  
  232.     filesystem::path output_path = filesystem::path(argv[2]);
  233.  
  234.     if (!(filesystem::exists(output_path.parent_path()) &&
  235.           filesystem::is_directory(output_path.parent_path()) &&
  236.           output_path.has_filename()))
  237.     {
  238.         std::cerr << "Неверно указан файл для выходных данных. "
  239.             "Возможно указанного расположения не существует или нет прав на запись." << '\n';
  240.         return 1;
  241.     }
  242.     std::ofstream output_file(output_path);
  243.  
  244.     if (!output_file.is_open()) {
  245.         std::cerr << "Неверно указан файл для выходных данных. "
  246.             "Возможно указанного расположения не существует или нет прав на запись." << '\n';
  247.         return 1;
  248.     }
  249.  
  250.     TaskParams params = {};
  251.  
  252.     try {
  253.         readInputFile(input_file, &params);
  254.         validateInputData(params);
  255.     } catch (const InvalidValueException& e) {
  256.         output_file << e.what();
  257.         return 1;
  258.     } catch (const InvalidInputFileException& e) {
  259.         output_file << e.what();
  260.         return 1;
  261.     }
  262.  
  263.     output_file << calcMinPrintingTime(params);
  264.  
  265.     // Закрыть файлы
  266.     input_file.close();
  267.     output_file.close();
  268.  
  269.     return 0;
  270. }
  271.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement