#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; class CPkg{ public: CPkg( std::string n ) : _name(std::move(n)) {} CPkg& addDep( std::string n ) { _deps.emplace_back( std::move(n) ); return *this; } bool operator<( const CPkg& oth ) const { return _name < oth._name; } std::string _name; std::vector< std::string > _deps; private: }; class CPkgSys{ public: CPkgSys& addPkg(const CPkg& p) { packages[p._name] = p._deps; return *this; } std::set install(std::list what) { std::set d = installed; std::queue q; std::set r; for (const auto& i : what) { q.push(i); if (d.emplace(i).second) r.emplace(i); } while (q.size()) { auto i = q.front(); q.pop(); auto it = packages.find(i); if (it == packages.end()) throw std::invalid_argument("Package not found."); for ( const auto& j : it->second ) { if (d.emplace(j).second) { r.emplace(j); q.push(j); } } } std::swap( installed, d ); return r; } private: std::unordered_map> packages; std::set installed; }; int main(void){ CPkgSys s; stringstream ss; s.addPkg(CPkg("ssh").addDep("sudo").addDep("apt")) .addPkg(CPkg("sudo").addDep("git").addDep("c++")); s.addPkg(CPkg("apt")) .addPkg(CPkg("c++").addDep("c").addDep("asm").addDep("fortran")); s.addPkg(CPkg("git")) .addPkg(CPkg("c").addDep("kekw")) .addPkg(CPkg("kekw")) .addPkg(CPkg("asm")) .addPkg(CPkg("fortran")); s.addPkg(CPkg("python").addDep("bash").addDep("sadge")) .addPkg(CPkg("karel").addDep("python")) .addPkg(CPkg("bash").addDep("sadge")) .addPkg(CPkg("sadge")) .addPkg(CPkg("cython").addDep("dev")); s.addPkg(CPkg("perl")); // ss << s; // assert(ss.str() == ""); ss.clear(); ss.str(""); set t1 = s.install(list {"sudo"}); assert(t1 == (set {"asm", "c", "c++", "fortran", "git", "kekw", "sudo"})); set t2 = s.install(list {"ssh", "c++"}); assert(t2 == (set {"apt", "ssh"})); // ss << s; // assert(ss.str() == "apt, asm, c, c++, fortran, git, kekw, ssh, sudo"); // ss.clear(); // ss.str(""); try{ set e = s.install(list {"karel", "cython"}); assert("Sem ses nemel dostat debilku" == nullptr); } catch(const invalid_argument & e){ assert(strcmp("Package not found.", e.what()) == 0); } set t3 = s.install(list {"karel", "fortran", "git"}); assert(t3 == (set {"bash", "karel", "python", "sadge"})); s.addPkg(CPkg("java").addDep("utils")) .addPkg(CPkg("utils").addDep("VB")) .addPkg(CPkg("VB").addDep("java")); set t4 = s.install(list {"java", "perl"}); assert(t4 == (set {"VB", "java", "perl", "utils"})); // ss << s; // assert(ss.str() == "VB, apt, asm, bash, c, c++, fortran, git, java, karel, kekw, perl, python, sadge, ssh, sudo, utils"); // ss.clear(); // ss.str(""); CPkgSys k; k.addPkg(CPkg("ssh").addDep("sudo").addDep("apt")) .addPkg(CPkg("sudo").addDep("git")); k.addPkg(CPkg("apt")); k.addPkg(CPkg("git")) .addPkg(CPkg("c").addDep("kekw")) .addPkg(CPkg("kekw")) .addPkg(CPkg("asm")) .addPkg(CPkg("fortran")); k.addPkg(CPkg("python").addDep("bash").addDep("sadge")) .addPkg(CPkg("karel").addDep("python")) .addPkg(CPkg("bash").addDep("sadge")) .addPkg(CPkg("sadge")); k.addPkg(CPkg("perl").addDep("no")); set t5 = k.install(list {"asm"}); assert(t5 == (set {"asm"})); set t6 = k.install(list {"python", "ssh"}); assert(t6 == (set {"apt", "bash", "git", "python", "sadge", "ssh", "sudo"})); try{ set t7 = k.install(list {"perl", "c"}); assert("Sem ses nemel dostat debilku" == nullptr); } catch(const invalid_argument & e){ assert(strcmp("Package not found.", e.what()) == 0); } set t8 = k.install(list {"c", "ssh", "karel"}); assert(t8 == (set {"c", "karel", "kekw"})); // ss << k; // assert(ss.str() == "apt, asm, bash, c, git, karel, kekw, python, sadge, ssh, sudo"); // ss.clear(); // ss.str(""); std::cout << "success!\n"; }