diff --git a/2017/puzzle-12-01.cc b/2017/puzzle-12-01.cc new file mode 100644 index 0000000..543533a --- /dev/null +++ b/2017/puzzle-12-01.cc @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +struct InTree +{ + constexpr auto visited() const noexcept -> bool { return visited_; } + constexpr void visit() { visited_ = true; } + +private: + bool visited_{false}; +}; + +using UInt = unsigned long; +using VisitMap = std::map; +using Connections = std::multimap; + +auto find_next_node(VisitMap& map) +{ + return std::find_if(map.begin(), map.end(), [](auto const& it) { return !it.second.visited(); }); +} + +auto main() -> int +{ + std::string line; + Connections connections; + + while (std::getline(std::cin, line) && !line.empty()) { + std::size_t end{0}; + auto from{std::stoul(line, &end)}; + assert(line.substr(end, 5) == " <-> "); + auto idx{end + 5}; + while (idx < line.size()) { + if (line[idx] == ',' || line[idx] == ' ') { + ++idx; + continue; + } + + auto to{std::stoul(line.substr(idx), &end)}; + connections.insert({from, to}); + connections.insert({to, from}); + idx += end; + } + } + + VisitMap connected0; + connected0.insert({0, InTree{}}); + while (true) { + auto it{find_next_node(connected0)}; + if (it == connected0.end()) { + break; + } + it->second.visit(); + + auto [it_begin, it_end] = connections.equal_range(it->first); + for (auto it2{it_begin}; it2 != it_end; ++it2) { + connected0.insert({it2->second, InTree{}}); + } + } + + std::cout << "Size of connected tree: " << connected0.size() << '\n'; + return 0; +} diff --git a/2017/puzzle-12-02.cc b/2017/puzzle-12-02.cc new file mode 100644 index 0000000..abff189 --- /dev/null +++ b/2017/puzzle-12-02.cc @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +using UInt = unsigned long; +using VisitMap = std::map; +using Connections = std::multimap; + +auto find_next_node(VisitMap& map) +{ + return std::find_if(map.begin(), map.end(), [](auto const& it) { return !it.second; }); +} + +auto main() -> int +{ + std::string line; + Connections connections; + + while (std::getline(std::cin, line) && !line.empty()) { + std::size_t end{0}; + auto from{std::stoul(line, &end)}; + assert(line.substr(end, 5) == " <-> "); + auto idx{end + 5}; + while (idx < line.size()) { + if (line[idx] == ',' || line[idx] == ' ') { + ++idx; + continue; + } + + auto to{std::stoul(line.substr(idx), &end)}; + connections.insert({from, to}); + connections.insert({to, from}); + idx += end; + } + } + + UInt group_count{0}; + while (!connections.empty()) { + VisitMap connected; + connected.insert({connections.begin()->first, false}); + while (true) { + auto it{find_next_node(connected)}; + if (it == connected.end()) { + break; + } + it->second = true; + + auto [it_begin, it_end] = connections.equal_range(it->first); + for (auto it2{it_begin}; it2 != it_end; ++it2) { + connected.insert({it2->second, false}); + } + connections.erase(it_begin, it_end); + } + ++group_count; + } + + std::cout << "Number of groups: " << group_count << '\n'; + return 0; +}