Advertisement
Guest User

Day04.hpp

a guest
Dec 4th, 2018
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.85 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. #include <queue>
  6. #include <array>
  7. #include <unordered_map>
  8. #include <map>
  9. #include <algorithm>
  10. #include <functional>
  11. #include <tuple>
  12. #include <numeric>
  13.  
  14. #include "Day.hpp"
  15.  
  16. struct TimeStamp {
  17.     int month, day, hour, minute;
  18.     std::string status;
  19. };
  20.  
  21. std::vector<TimeStamp> getTimeStamps(std::ifstream& in);
  22.  
  23. void sortStamps(std::vector<TimeStamp>& stamps);
  24.  
  25. std::unordered_map<int, std::vector<std::pair<int, int>>> mapStamps(const std::vector<TimeStamp>& stamps);
  26.  
  27. template<>
  28. void Day<4>::solve1(std::ifstream& in, std::ostream& out) {
  29.     std::vector<TimeStamp> stamps = getTimeStamps(in);
  30.     std::unordered_map<int, std::vector<std::pair<int, int>>> idToSleep = mapStamps(stamps);
  31.  
  32.     // Find ID with most sleep time
  33.     int idMax = 0, maxTimeSum = 0;
  34.     for (const auto& i : idToSleep) {
  35.         int currTimeSum = std::accumulate(i.second.begin(), i.second.end(), 0, [](const int& currSum, const std::pair<int, int>& p){ return currSum + p.second - p.first; });
  36.  
  37.         if (maxTimeSum < currTimeSum) {
  38.             idMax = i.first;
  39.             maxTimeSum = currTimeSum;
  40.         }
  41.     }
  42.  
  43.     // Go through time vector and get minute most sleeped on.
  44.     // Decided to brute force it since there are only 60 minutes in an hour...
  45.     auto bestVector = idToSleep[idMax];
  46.     std::pair<int, int> maxFrequency = { 0, 0 };
  47.  
  48.     for (int i = 0; i < 60; ++i) {
  49.         std::pair<int, int> currFrequency = { i, 0 };
  50.         for (auto p : bestVector) {
  51.             if (i >= p.first && i < p.second)
  52.                 ++currFrequency.second;
  53.         }
  54.  
  55.         if (maxFrequency.second < currFrequency.second)
  56.             maxFrequency = currFrequency;
  57.     }
  58.  
  59.     out << idMax * maxFrequency.first << std::endl;
  60. }
  61.  
  62. template<>
  63. void Day<4>::solve2(std::ifstream& in, std::ostream& out) {
  64.     std::vector<TimeStamp> stamps = getTimeStamps(in);
  65.     std::unordered_map<int, std::vector<std::pair<int, int>>> idToSleep = mapStamps(stamps);
  66.  
  67.     std::pair<int, int> maxFrequency = { 0, 0 };
  68.     int idMax = 0;
  69.    
  70.     // Taken from solve1 and just iterating over all ids rather than just one.
  71.     for (auto i : idToSleep) {
  72.         auto currVector = i.second;
  73.  
  74.         for (int k = 0; k < 60; ++k) {
  75.             std::pair<int, int> currFrequency = { k, 0 };
  76.             for (auto p : currVector) {
  77.                 if (k >= p.first && k < p.second)
  78.                     ++currFrequency.second;
  79.             }
  80.  
  81.             if (maxFrequency.second < currFrequency.second) {
  82.                 maxFrequency = currFrequency;
  83.                 idMax = i.first;
  84.             }
  85.         }
  86.     }
  87.  
  88.     out << idMax * maxFrequency.first << std::endl;
  89. }
  90.  
  91. // Extracts time stamps from input and calls sort on them
  92. // then returns time stamps sorted
  93. std::vector<TimeStamp> getTimeStamps(std::ifstream& in) {
  94.     std::string stampDate, stampTime, status;
  95.     std::vector<TimeStamp> stamps;
  96.  
  97.     while (in >> stampDate >> stampTime && std::getline(in, status)) {
  98.         int month = std::stoi(stampDate.substr(6, 8));
  99.         int day = std::stoi(stampDate.substr(9, 11));
  100.         int hour = std::stoi(stampTime.substr(0, 2));
  101.         int minute = std::stoi(stampTime.substr(3, 5));
  102.  
  103.         stamps.push_back({month, day, hour, minute, status.substr(1)});
  104.     }
  105.  
  106.     sortStamps(stamps);
  107.  
  108.     return stamps;
  109. }
  110.  
  111. void sortStamps(std::vector<TimeStamp>& stamps) {
  112.     std::array<std::queue<TimeStamp>, 10> digits;
  113.  
  114.     // Radix sort
  115.     for (size_t i = 0; i < 8; ++i) {
  116.         for (TimeStamp& s : stamps) {
  117.             int key;
  118.             if (i <= 1)
  119.                 key = s.minute;
  120.             else if (i <= 3)
  121.                 key = s.hour;
  122.             else if (i <= 5)
  123.                 key = s.day;
  124.             else
  125.                 key = s.month;
  126.  
  127.             if (i % 2 == 0)
  128.                 key %= 10;
  129.             else
  130.                 key /= 10;
  131.  
  132.             digits[key].push(s);
  133.         }
  134.  
  135.         size_t index = 0;
  136.         for (std::queue<TimeStamp>& q : digits) {
  137.             while (!q.empty()) {
  138.                 stamps[index] = q.front();
  139.                 q.pop();
  140.                 ++index;
  141.             }
  142.         }
  143.     }
  144. }
  145.  
  146. std::unordered_map<int, std::vector<std::pair<int, int>>> mapStamps(const std::vector<TimeStamp>& stamps) {
  147.     std::unordered_map<int, std::vector<std::pair<int, int>>> idToSleep;
  148.    
  149.     int id, startSleep;
  150.     for (const TimeStamp& s : stamps) {
  151.         if (s.status.find('G') != std::string::npos) {
  152.             size_t start = s.status.find("#");
  153.             id = std::stoi(s.status.substr(start + 1, s.status.substr(start).find(' ')));
  154.         } else if (s.status == "falls asleep") {
  155.             startSleep = s.minute;
  156.         } else {
  157.             idToSleep[id].push_back({startSleep, s.minute});
  158.         }
  159.     }
  160.  
  161.     return idToSleep;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement