W_A_S_A_B_I

jhdsf2i3h98

Nov 27th, 2023
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.40 KB | Source Code | 0 0
  1. #include <array>
  2. #include <cassert>
  3. #include <chrono>
  4. #include <iomanip>
  5. #include <iostream>
  6. #include <sstream>
  7. #include <string>
  8. #include <tuple>
  9. #include <unordered_map>
  10. #include <vector>
  11.  
  12. using namespace std;
  13.  
  14. class VehiclePlate {
  15. private:
  16.     auto AsTuple() const {
  17.         return tie(letters_, digits_, region_);
  18.     }
  19.  
  20. public:
  21.     bool operator==(const VehiclePlate& other) const {
  22.         return AsTuple() == other.AsTuple();
  23.     }
  24.  
  25.     VehiclePlate(char l0, char l1, int digits, char l2, int region)
  26.         : letters_{l0, l1, l2}
  27.         , digits_(digits)
  28.         , region_(region) {
  29.     }
  30.  
  31.     string ToString() const {
  32.         ostringstream out;
  33.         out << letters_[0] << letters_[1];
  34.  
  35.         // чтобы дополнить цифровую часть номера слева нулями
  36.         // до трёх цифр, используем подобные манипуляторы:
  37.         // setfill задаёт символ для заполнения,
  38.         // right задаёт выравнивание по правому краю,
  39.         // setw задаёт минимальное желаемое количество знаков
  40.         out << setfill('0') << right << setw(3) << digits_;
  41.         out << letters_[2] << setw(2) << region_;
  42.  
  43.         return out.str();
  44.     }
  45.  
  46. private:
  47.     array<char, 3> letters_;
  48.     int digits_;
  49.     int region_;
  50. };
  51.  
  52. ostream& operator<<(ostream& out, VehiclePlate plate) {
  53.     out << plate.ToString();
  54.     return out;
  55. }
  56.  
  57. // возьмите реализацию хешера из прошлого задания
  58. class VehiclePlateHasher {
  59. public:
  60.     size_t operator()(const VehiclePlate& plate) const {
  61.         // измените эту функцию, чтобы она учитывала все данные номера
  62.         // рекомендуется использовать метод ToString() и существующий
  63.         // класс hash<string>
  64.         return hasher_(plate.ToString());
  65.     }
  66. private:
  67.     hash<string> hasher_;
  68.  
  69. };
  70.  
  71. // выбросьте это исключение в случае ошибки парковки
  72. struct ParkingException {
  73. };
  74.  
  75. template <typename Clock>
  76. class Parking {
  77.     // при обращении к типу внутри шаблонного параметра мы обязаны использовать
  78.     // typename; чтобы этого избежать, объявим псевдонимы для нужных типов
  79.     using Duration = typename Clock::duration;
  80.     using TimePoint = typename Clock::time_point;
  81.  
  82. public:
  83.     Parking(int cost_per_second) : cost_per_second_(cost_per_second) {}
  84.  
  85.     // запарковать машину с указанным номером
  86.     void Park(VehiclePlate car) {
  87.         // место для вашей реализации
  88.         chrono::system_clock::time_point now = chrono::system_clock::now();
  89.         ParkingException exception;
  90.         if (now_parked_.count(car)){
  91.             throw exception;
  92.         } else {
  93.             now_parked_[car] = now;
  94.         }
  95.     }
  96.  
  97.     // забрать машину с указанным номером
  98.     void Withdraw(const VehiclePlate& car) {
  99.         // место для вашей реализации
  100.         chrono::system_clock::time_point now = chrono::system_clock::now();
  101.         ParkingException exception;
  102.         if (now_parked_.count(car)){
  103.             complete_parks_[car] += (now - now_parked_.at(car));
  104.             now_parked_.erase(car);
  105.         } else {
  106.             throw exception;
  107.         }
  108.     }
  109.  
  110.     // получить счёт за конкретный автомобиль
  111.     int64_t GetCurrentBill(const VehiclePlate& car) const {
  112.         // место для вашей реализации
  113.         chrono::system_clock::time_point now = chrono::system_clock::now();
  114.         int64_t res = 0;
  115.         if (now_parked_.count(car)){
  116.             chrono::system_clock::duration dur = (now - now_parked_.at(car));
  117.             res += (chrono::duration_cast<chrono::seconds>(dur).count() * cost_per_second_);
  118.         }
  119.         if (complete_parks_.count(car)){
  120.             res += (chrono::duration_cast<chrono::seconds>(complete_parks_.at(car)).count() * cost_per_second_);
  121.         }
  122.         return res;
  123.        
  124.     }
  125.  
  126.     // завершить расчётный период
  127.     // те машины, которые находятся на парковке на данный момент, должны
  128.     // остаться на парковке, но отсчёт времени для них начинается с нуля
  129.     unordered_map<VehiclePlate, int64_t, VehiclePlateHasher> EndPeriodAndGetBills() {
  130.         // место для вашей реализации
  131.         unordered_map<VehiclePlate, int64_t, VehiclePlateHasher> res_map;
  132.  
  133.         for (auto [car, dur] : complete_parks_){
  134.             res_map[car] = GetCurrentBill(car);
  135.         }
  136.         for (auto [car, point] : now_parked_){
  137.             if (! complete_parks_.count(car)){
  138.                 res_map[car] = GetCurrentBill(car);
  139.             }
  140.             now_parked_[car] = chrono::system_clock::now();
  141.         }
  142.         complete_parks_.clear();
  143.         return res_map;
  144.     }
  145.  
  146.     // не меняйте этот метод
  147.     auto& GetNowParked() const {
  148.         return now_parked_;
  149.     }
  150.  
  151.     // не меняйте этот метод
  152.     auto& GetCompleteParks() const {
  153.         return complete_parks_;
  154.     }
  155.  
  156. private:
  157.     int cost_per_second_;
  158.     unordered_map<VehiclePlate, TimePoint, VehiclePlateHasher> now_parked_;
  159.     unordered_map<VehiclePlate, Duration, VehiclePlateHasher> complete_parks_;
  160. };
  161.  
  162. // эти часы удобно использовать для тестирования
  163. // они покажут столько времени, сколько вы задали явно
  164. class TestClock {
  165. public:
  166.     using time_point = chrono::system_clock::time_point;
  167.     using duration = chrono::system_clock::duration;
  168.  
  169.     static void SetNow(int seconds) {
  170.         current_time_ = seconds;
  171.     }
  172.  
  173.     static time_point now() {
  174.         return start_point_ + chrono::seconds(current_time_);
  175.     }
  176.  
  177. private:
  178.     inline static time_point start_point_ = chrono::system_clock::now();
  179.     inline static int current_time_ = 0;
  180. };
  181.  
  182. int main() {
  183.     Parking<TestClock> parking(10);
  184.  
  185.     TestClock::SetNow(10);
  186.     parking.Park({'A', 'A', 111, 'A', 99});
  187.  
  188.     TestClock::SetNow(20);
  189.     parking.Withdraw({'A', 'A', 111, 'A', 99});
  190.     parking.Park({'B', 'B', 222, 'B', 99});
  191.  
  192.     TestClock::SetNow(40);
  193.     assert(parking.GetCurrentBill({'A', 'A', 111, 'A', 99}) == 100);
  194.     assert(parking.GetCurrentBill({'B', 'B', 222, 'B', 99}) == 200);
  195.     parking.Park({'A', 'A', 111, 'A', 99});
  196.  
  197.     TestClock::SetNow(50);
  198.     assert(parking.GetCurrentBill({'A', 'A', 111, 'A', 99}) == 200);
  199.     assert(parking.GetCurrentBill({'B', 'B', 222, 'B', 99}) == 300);
  200.     assert(parking.GetCurrentBill({'C', 'C', 333, 'C', 99}) == 0);
  201.     parking.Withdraw({'B', 'B', 222, 'B', 99});
  202.  
  203.     TestClock::SetNow(70);
  204.     {
  205.         // проверим счёт
  206.         auto bill = parking.EndPeriodAndGetBills();
  207.  
  208.         // так как внутри макроса используется запятая,
  209.         // нужно заключить его аргумент в дополнительные скобки
  210.         assert((bill
  211.                 == unordered_map<VehiclePlate, int64_t, VehiclePlateHasher>{
  212.                    {{'A', 'A', 111, 'A', 99}, 400},
  213.                    {{'B', 'B', 222, 'B', 99}, 300},
  214.                }));
  215.     }
  216.  
  217.     TestClock::SetNow(80);
  218.     {
  219.         // проверим счёт
  220.         auto bill = parking.EndPeriodAndGetBills();
  221.  
  222.         // так как внутри макроса используется запятая,
  223.         // нужно заключить его аргумент в дополнительные скобки
  224.         assert((bill
  225.                 == unordered_map<VehiclePlate, int64_t, VehiclePlateHasher>{
  226.                    {{'A', 'A', 111, 'A', 99}, 100},
  227.                }));
  228.     }
  229.  
  230.     try {
  231.         parking.Park({'A', 'A', 111, 'A', 99});
  232.         assert(false);
  233.     }
  234.     catch (ParkingException) {
  235.     }
  236.  
  237.     try {
  238.         parking.Withdraw({'B', 'B', 222, 'B', 99});
  239.         assert(false);
  240.     }
  241.     catch (ParkingException) {
  242.     }
  243.  
  244.     cout << "Success!"s << endl;
  245. }
Add Comment
Please, Sign In to add comment