#include #include #include //#define BIGBOY #if defined(BIGBOY) #define TOTAL_SPACE 3000000000 #define NEEDED_SPACE 700000000 #else #define TOTAL_SPACE 70000000 #define NEEDED_SPACE 30000000 #endif using namespace std; enum FsNodeType { NODE_DIR, NODE_FILE }; struct FsNode { FsNodeType type; string name; size_t size; }; struct FsFile : FsNode { }; struct FsDir : FsNode { ~FsDir() { for (auto e : this->entries) { FsNode *node = e.second; if (node->type == NODE_DIR) { FsDir *dir = (FsDir *)node; delete dir; } else if (node->type == NODE_FILE) { FsFile *file = (FsFile *)node; delete file; } } this->entries.clear(); } FsDir *parent; map entries; }; void print_node(FsNode *node, unsigned depth = 0) { for (unsigned i = 0; i < depth; i++) clog << " "; clog << "- " << node->name << " ("; switch (node->type) { case NODE_DIR: clog << "dir"; break; case NODE_FILE: clog << "file"; break; } clog << ", "; clog << "size=" << node->size; clog << ")" << endl; if (node->type == NODE_DIR) { FsDir *dir = (FsDir *)node; for (auto e : dir->entries) print_node(e.second, depth + 1); } } size_t calc_size(FsDir &dir) { size_t size = 0; for (auto e : dir.entries) { FsNode *node = e.second; if (!node->size && node->type == NODE_DIR) calc_size(*(FsDir *)node); size += node->size; } dir.size = size; return size; } FsDir parse() { FsDir root; root.type = NODE_DIR; root.name = "/"; root.parent = NULL; FsDir *dir = &root; for (string line; getline(cin, line);) { if (line.at(0) != '$' || line.at(1) != ' ') { unsigned split = line.find(' '); string first = line.substr(0, split); string name = line.substr(split + 1); if (first == "dir") { FsDir *newdir = new FsDir; newdir->type = NODE_DIR; newdir->name = name; newdir->size = 0; newdir->parent = dir; dir->entries[name] = newdir; } else { size_t size = stoll(first); FsFile *newfile = new FsFile; newfile->type = NODE_FILE; newfile->name = name; newfile->size = size; dir->entries[name] = newfile; } } if (line.substr(2, 3) == "ls") { // derp? } else if (line.substr(2, 3) == "cd ") { string name = line.substr(5); if (name == "/") { dir = &root; } else if (name == "..") { if (dir->parent) dir = dir->parent; } else { auto it = dir->entries.find(name); if (it != dir->entries.end()) { FsNode *node = it->second; if (node->type == NODE_DIR) { dir = (FsDir *)node; } } } } } calc_size(root); //print_node(&root); return root; } size_t p1(const FsDir &dir) { size_t count = 0; if (dir.size <= 100000) count += dir.size; for (auto e : dir.entries) { FsNode *node = e.second; if (node->type == NODE_DIR) count += p1(*(FsDir *)node); } return count; } size_t p2(const FsDir &dir, size_t target = 0) { if (!target) target = dir.size - (TOTAL_SPACE - NEEDED_SPACE); size_t smallest = NEEDED_SPACE; if (dir.size >= target && dir.size < smallest) smallest = dir.size; for (auto e : dir.entries) { FsNode *node = e.second; if (node->type == NODE_DIR) { size_t size = p2(*(FsDir *)node, target); if (size >= target && size < smallest) smallest = size; } } return smallest; } int main() { auto input = parse(); cout << p1(input) << endl; cout << p2(input) << endl; }