Add solutions for 2018 day 4
This commit is contained in:
		
							
								
								
									
										148
									
								
								2018/puzzle-04-01.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								2018/puzzle-04-01.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | |||||||
|  | // | ||||||
|  | // Created by Matthew Gretton-Dann on 01/12/2022. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include <cstdlib> | ||||||
|  | #include <iomanip> | ||||||
|  | #include <iostream> | ||||||
|  | #include <map> | ||||||
|  | #include <numeric> | ||||||
|  | #include <set> | ||||||
|  | #include <string> | ||||||
|  | #include <utility> | ||||||
|  | #include <vector> | ||||||
|  |  | ||||||
|  | using UInt = std::uint64_t; | ||||||
|  |  | ||||||
|  | using namespace std::string_literals; | ||||||
|  |  | ||||||
|  | struct Event | ||||||
|  | { | ||||||
|  |   explicit Event(std::string const& s) | ||||||
|  |   { | ||||||
|  |     UInt pos{1}; | ||||||
|  |     std::size_t l{0}; | ||||||
|  |     std::stoull(s.substr(pos)); | ||||||
|  |     timestamp_ = std::stoull(s.substr(pos), &l);  // year | ||||||
|  |     pos += l + 1; | ||||||
|  |     timestamp_ *= 12; | ||||||
|  |     timestamp_ += std::stoull(s.substr(pos), &l) - 1;  // month | ||||||
|  |     pos += l + 1; | ||||||
|  |     timestamp_ *= 31;                                  // Just need order not actual values. | ||||||
|  |     timestamp_ += std::stoull(s.substr(pos), &l) - 1;  // day | ||||||
|  |     pos += l + 1; | ||||||
|  |     timestamp_ *= 24; | ||||||
|  |     timestamp_ += std::stoull(s.substr(pos), &l);  // hour | ||||||
|  |     pos += l + 1; | ||||||
|  |     timestamp_ *= 60; | ||||||
|  |     timestamp_ += std::stoull(s.substr(pos), &l);  // minute | ||||||
|  |     pos += l + 2; | ||||||
|  |     if (s.substr(pos) == "falls asleep"s) { | ||||||
|  |       wake_up_ = false; | ||||||
|  |       guard_ = 0; | ||||||
|  |     } | ||||||
|  |     else if (s.substr(pos) == "wakes up"s) { | ||||||
|  |       wake_up_ = true; | ||||||
|  |       guard_ = 0; | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       wake_up_ = true; | ||||||
|  |       guard_ = std::stoull(s.substr(pos + 7)); | ||||||
|  |       assert(guard_ != 0); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto wakes_up() const noexcept -> bool { return wake_up_; } | ||||||
|  |   [[nodiscard]] auto guard_id() const noexcept -> UInt { return guard_; } | ||||||
|  |   [[nodiscard]] auto timestamp() const noexcept -> UInt { return timestamp_; } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto operator<(Event const& r) const noexcept -> bool | ||||||
|  |   { | ||||||
|  |     if (timestamp_ < r.timestamp_) { | ||||||
|  |       return true; | ||||||
|  |     } | ||||||
|  |     if (timestamp_ > r.timestamp_) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if (r.wake_up_) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     return wake_up_; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |   UInt timestamp_{0}; | ||||||
|  |   UInt guard_{0}; | ||||||
|  |   bool wake_up_{false}; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | auto print_timestamp(UInt timestamp) | ||||||
|  | { | ||||||
|  |   std::cout << "[" << timestamp << ": " << timestamp / static_cast<UInt>(24 * 60 * 31 * 12) << "-" | ||||||
|  |             << std::setw(2) << std::setfill('0') | ||||||
|  |             << 1 + timestamp / static_cast<UInt>(24 * 60 * 31) % 12 << "-" << std::setw(2) | ||||||
|  |             << std::setfill('0') << 1 + (timestamp / static_cast<UInt>(24 * 60)) % 31 << " " | ||||||
|  |             << std::setw(2) << std::setfill('0') << (timestamp / 60) % 24 << ":" << std::setw(2) | ||||||
|  |             << std::setfill('0') << timestamp % 60 << "]"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | auto how_sleepy(std::vector<UInt> const& guard) -> UInt | ||||||
|  | { | ||||||
|  |   return std::accumulate(guard.begin(), guard.end(), UInt{0}, [](UInt a, UInt b) { return a + b; }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | auto main() -> int | ||||||
|  | { | ||||||
|  |   std::string line; | ||||||
|  |   std::vector<Event> events; | ||||||
|  |  | ||||||
|  |   while (std::getline(std::cin, line)) { | ||||||
|  |     events.emplace_back(line); | ||||||
|  |   } | ||||||
|  |   std::sort(events.begin(), events.end()); | ||||||
|  |   std::map<UInt, std::vector<UInt>> guard_sleep_map; | ||||||
|  |   auto current_it{guard_sleep_map.begin()}; | ||||||
|  |   UInt asleep_from{0}; | ||||||
|  |  | ||||||
|  |   for (auto const& e : events) { | ||||||
|  |     if (e.wakes_up()) { | ||||||
|  |       if (e.guard_id() != 0) { | ||||||
|  |         auto result = guard_sleep_map.insert({e.guard_id(), std::vector<UInt>(60, 0)}); | ||||||
|  |         current_it = result.first; | ||||||
|  |         assert(asleep_from == 0); | ||||||
|  |         print_timestamp(e.timestamp()); | ||||||
|  |         std::cout << ": Guard " << current_it->first << " starts duty.\n"; | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |         assert(asleep_from != 0); | ||||||
|  |         for (UInt i = asleep_from; i != e.timestamp(); ++i) { | ||||||
|  |           ++(current_it->second[i % 60]); | ||||||
|  |         } | ||||||
|  |         print_timestamp(e.timestamp()); | ||||||
|  |         std::cout << ": Guard " << current_it->first << " wakes up after " | ||||||
|  |                   << e.timestamp() - asleep_from << " minutes sleep.  Has slept a total of " | ||||||
|  |                   << how_sleepy(current_it->second) << " minutes.\n"; | ||||||
|  |         asleep_from = 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       assert(asleep_from == 0); | ||||||
|  |       asleep_from = e.timestamp(); | ||||||
|  |       print_timestamp(e.timestamp()); | ||||||
|  |       std::cout << ": Guard " << current_it->first << " goes to sleep.\n"; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   auto sleepiest_guard{std::max_element(guard_sleep_map.begin(), guard_sleep_map.end(), | ||||||
|  |                                         [](auto const& lhs, auto const& rhs) { | ||||||
|  |                                           return how_sleepy(lhs.second) < how_sleepy(rhs.second); | ||||||
|  |                                         })}; | ||||||
|  |   auto sleepiest_guard_id{sleepiest_guard->first}; | ||||||
|  |   auto sleepiest_minute{ | ||||||
|  |     std::max_element(sleepiest_guard->second.begin(), sleepiest_guard->second.end()) - | ||||||
|  |     sleepiest_guard->second.begin()}; | ||||||
|  |   std::cout << "Busiest guard: " << sleepiest_guard_id << " was asleep most in minute " | ||||||
|  |             << sleepiest_minute << "\n"; | ||||||
|  |   std::cout << "Result: " << sleepiest_guard_id * sleepiest_minute << "\n"; | ||||||
|  |   return EXIT_SUCCESS; | ||||||
|  | } | ||||||
							
								
								
									
										153
									
								
								2018/puzzle-04-02.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								2018/puzzle-04-02.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | |||||||
|  | // | ||||||
|  | // Created by Matthew Gretton-Dann on 01/12/2022. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include <cstdlib> | ||||||
|  | #include <iomanip> | ||||||
|  | #include <iostream> | ||||||
|  | #include <map> | ||||||
|  | #include <numeric> | ||||||
|  | #include <set> | ||||||
|  | #include <string> | ||||||
|  | #include <utility> | ||||||
|  | #include <vector> | ||||||
|  |  | ||||||
|  | using UInt = std::uint64_t; | ||||||
|  |  | ||||||
|  | using namespace std::string_literals; | ||||||
|  |  | ||||||
|  | struct Event | ||||||
|  | { | ||||||
|  |   explicit Event(std::string const& s) | ||||||
|  |   { | ||||||
|  |     UInt pos{1}; | ||||||
|  |     std::size_t l{0}; | ||||||
|  |     std::stoull(s.substr(pos)); | ||||||
|  |     timestamp_ = std::stoull(s.substr(pos), &l);  // year | ||||||
|  |     pos += l + 1; | ||||||
|  |     timestamp_ *= 12; | ||||||
|  |     timestamp_ += std::stoull(s.substr(pos), &l) - 1;  // month | ||||||
|  |     pos += l + 1; | ||||||
|  |     timestamp_ *= 31;                                  // Just need order not actual values. | ||||||
|  |     timestamp_ += std::stoull(s.substr(pos), &l) - 1;  // day | ||||||
|  |     pos += l + 1; | ||||||
|  |     timestamp_ *= 24; | ||||||
|  |     timestamp_ += std::stoull(s.substr(pos), &l);  // hour | ||||||
|  |     pos += l + 1; | ||||||
|  |     timestamp_ *= 60; | ||||||
|  |     timestamp_ += std::stoull(s.substr(pos), &l);  // minute | ||||||
|  |     pos += l + 2; | ||||||
|  |     if (s.substr(pos) == "falls asleep"s) { | ||||||
|  |       wake_up_ = false; | ||||||
|  |       guard_ = 0; | ||||||
|  |     } | ||||||
|  |     else if (s.substr(pos) == "wakes up"s) { | ||||||
|  |       wake_up_ = true; | ||||||
|  |       guard_ = 0; | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       wake_up_ = true; | ||||||
|  |       guard_ = std::stoull(s.substr(pos + 7)); | ||||||
|  |       assert(guard_ != 0); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto wakes_up() const noexcept -> bool { return wake_up_; } | ||||||
|  |   [[nodiscard]] auto guard_id() const noexcept -> UInt { return guard_; } | ||||||
|  |   [[nodiscard]] auto timestamp() const noexcept -> UInt { return timestamp_; } | ||||||
|  |  | ||||||
|  |   [[nodiscard]] auto operator<(Event const& r) const noexcept -> bool | ||||||
|  |   { | ||||||
|  |     if (timestamp_ < r.timestamp_) { | ||||||
|  |       return true; | ||||||
|  |     } | ||||||
|  |     if (timestamp_ > r.timestamp_) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     if (r.wake_up_) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |     return wake_up_; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |   UInt timestamp_{0}; | ||||||
|  |   UInt guard_{0}; | ||||||
|  |   bool wake_up_{false}; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | auto print_timestamp(UInt timestamp) | ||||||
|  | { | ||||||
|  |   std::cout << "[" << timestamp << ": " << timestamp / static_cast<UInt>(24 * 60 * 31 * 12) << "-" | ||||||
|  |             << std::setw(2) << std::setfill('0') | ||||||
|  |             << 1 + timestamp / static_cast<UInt>(24 * 60 * 31) % 12 << "-" << std::setw(2) | ||||||
|  |             << std::setfill('0') << 1 + (timestamp / static_cast<UInt>(24 * 60)) % 31 << " " | ||||||
|  |             << std::setw(2) << std::setfill('0') << (timestamp / 60) % 24 << ":" << std::setw(2) | ||||||
|  |             << std::setfill('0') << timestamp % 60 << "]"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | auto how_sleepy(std::vector<UInt> const& guard) -> UInt | ||||||
|  | { | ||||||
|  |   return std::accumulate(guard.begin(), guard.end(), UInt{0}, [](UInt a, UInt b) { return a + b; }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | auto main() -> int | ||||||
|  | { | ||||||
|  |   std::string line; | ||||||
|  |   std::vector<Event> events; | ||||||
|  |  | ||||||
|  |   while (std::getline(std::cin, line)) { | ||||||
|  |     events.emplace_back(line); | ||||||
|  |   } | ||||||
|  |   std::sort(events.begin(), events.end()); | ||||||
|  |   std::map<UInt, std::vector<UInt>> guard_sleep_map; | ||||||
|  |   auto current_it{guard_sleep_map.begin()}; | ||||||
|  |   UInt asleep_from{0}; | ||||||
|  |  | ||||||
|  |   for (auto const& e : events) { | ||||||
|  |     if (e.wakes_up()) { | ||||||
|  |       if (e.guard_id() != 0) { | ||||||
|  |         auto result = guard_sleep_map.insert({e.guard_id(), std::vector<UInt>(60, 0)}); | ||||||
|  |         current_it = result.first; | ||||||
|  |         assert(asleep_from == 0); | ||||||
|  |         print_timestamp(e.timestamp()); | ||||||
|  |         std::cout << ": Guard " << current_it->first << " starts duty.\n"; | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |         assert(asleep_from != 0); | ||||||
|  |         for (UInt i = asleep_from; i != e.timestamp(); ++i) { | ||||||
|  |           ++(current_it->second[i % 60]); | ||||||
|  |         } | ||||||
|  |         print_timestamp(e.timestamp()); | ||||||
|  |         std::cout << ": Guard " << current_it->first << " wakes up after " | ||||||
|  |                   << e.timestamp() - asleep_from << " minutes sleep.  Has slept a total of " | ||||||
|  |                   << how_sleepy(current_it->second) << " minutes.\n"; | ||||||
|  |         asleep_from = 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       assert(asleep_from == 0); | ||||||
|  |       asleep_from = e.timestamp(); | ||||||
|  |       print_timestamp(e.timestamp()); | ||||||
|  |       std::cout << ": Guard " << current_it->first << " goes to sleep.\n"; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   UInt max_minute{0}; | ||||||
|  |   UInt max_score{0}; | ||||||
|  |   for (auto const& guard_sleep : guard_sleep_map) { | ||||||
|  |     auto sleepiest_minute{std::max_element(guard_sleep.second.begin(), guard_sleep.second.end())}; | ||||||
|  |     UInt const score{guard_sleep.first * (sleepiest_minute - guard_sleep.second.begin())}; | ||||||
|  |     if (*sleepiest_minute > max_minute) { | ||||||
|  |       max_score = score; | ||||||
|  |       max_minute = *sleepiest_minute; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     std::cout << "Guard " << guard_sleep.first << " slept most for " << *sleepiest_minute | ||||||
|  |               << " minutes at " << sleepiest_minute - guard_sleep.second.begin() | ||||||
|  |               << " score: " << score << "\n"; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   std::cout << "Result: " << max_score << "\n"; | ||||||
|  |   return EXIT_SUCCESS; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user