1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include "Hash.hpp"

struct Item;
using ItemPtr = std::shared_ptr<Item>;
using Dependencies = Hash<std::string, ItemPtr>;
struct Item {
   Item(std::string name) : name(std::move(name)), dependencies(32) {
   }
   std::string name;
   Dependencies dependencies;
};

int main() {
   Hash<std::string, ItemPtr> items(32);

   auto lookup = [&items](const std::string& name) -> ItemPtr {
      auto it = items.find(name);
      if (it == items.end()) {
	 auto item = std::make_shared<Item>(name);
	 std::tie(it, std::ignore) = items.insert(std::make_pair(name, item));
      }
      return it->second;
   };

   std::string line;
   while (std::getline(std::cin, line)) {
      std::istringstream in(line);
      std::string name;
      if (!(in >> name)) continue;
      auto item = lookup(name);
      while (in >> name) {
	 auto dep = lookup(name);
	 item->dependencies.insert(std::make_pair(name, dep));
      }
   }

   for (auto& object: items) {
      auto item = object.second;
      std::cout << item->name << ":";
      for (auto& depobj: item->dependencies) {
	 auto dep = depobj.second;
	 std::cout << " " << dep->name;
      }
      std::cout << std::endl;
   }
}