#include #include #include #include namespace { struct factors_iterator { factors_iterator() : f(-1) {} factors_iterator(int f, int n) : f(f), n(n), upper(std::sqrt(n)) {} auto operator!=(const factors_iterator &other) const -> bool { return f != other.f; } auto operator*() const -> int { return f; } auto operator++() -> factors_iterator & { // ‹f› yielded a prime if (f > upper || n == 1) { f = -1; return *this; } do { ++f; } while (f <= upper && n % f != 0); // ‹n› is a prime if (f > upper) { f = n; } while (n % f == 0) { n /= f; } return *this; } private: int f; int n; int upper; }; struct factors { factors(int n) : n(n) {} auto begin() const -> factors_iterator { return ++factors_iterator(1, n); } auto end() const -> factors_iterator { return factors_iterator(); } private: int n; }; void dfs(std::unordered_map> &graph, std::vector &visited, int u) { visited[u] = true; for (auto v : graph[u]) { if (!visited[v]) { dfs(graph, visited, v); } } } } // namespace class Solution { public: bool canTraverseAllPairs(const std::vector &nums) { auto n = nums.size(); std::unordered_map gcd; std::unordered_map> neighbors; for (auto i = 0u; i < n; ++i) { for (auto f : factors(nums[i])) { if (gcd.contains(f)) { int u = i; int v = gcd[f]; neighbors[u].push_back(v); neighbors[v].push_back(u); } gcd[f] = i; } } std::vector visited(n, false); dfs(neighbors, visited, 0); return std::find(visited.begin(), visited.end(), false) == visited.end(); } }; #ifdef _MF_TEST #include TEST(examples, no_1) { Solution s; EXPECT_TRUE(s.canTraverseAllPairs(std::vector{2, 3, 6})); } TEST(examples, no_2) { Solution s; EXPECT_FALSE(s.canTraverseAllPairs(std::vector{3, 9, 5})); } TEST(examples, no_3) { Solution s; EXPECT_TRUE(s.canTraverseAllPairs(std::vector{4, 3, 12, 8})); } TEST(factors, prime_2) { std::vector fs; for (auto f : factors(2)) { fs.push_back(f); } EXPECT_EQ(fs, std::vector{2}); } TEST(factors, prime_7) { std::vector fs; for (auto f : factors(7)) { fs.push_back(f); } EXPECT_EQ(fs, std::vector{7}); } TEST(factors, prime_29) { std::vector fs; for (auto f : factors(29)) { fs.push_back(f); } EXPECT_EQ(fs, std::vector{29}); } TEST(factors, composite_6) { std::vector fs; for (auto f : factors(6)) { fs.push_back(f); } EXPECT_EQ(fs, (std::vector{2, 3})); } TEST(factors, composite_15) { std::vector fs; for (auto f : factors(15)) { fs.push_back(f); } EXPECT_EQ(fs, (std::vector{3, 5})); } TEST(factors, composite_1024) { std::vector fs; for (auto f : factors(1024)) { fs.push_back(f); } EXPECT_EQ(fs, std::vector{2}); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } #endif