4 changed files with 1273 additions and 1 deletions
			
			
		@ -0,0 +1,162 @@ | 
				
			|||
#include <iostream> | 
				
			|||
#include <vector> | 
				
			|||
#include <map> | 
				
			|||
 | 
				
			|||
using namespace std; | 
				
			|||
 | 
				
			|||
enum FsNodeType { | 
				
			|||
    NODE_DIR, | 
				
			|||
    NODE_FILE | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
struct FsNode { | 
				
			|||
    FsNodeType type; | 
				
			|||
    string name; | 
				
			|||
    unsigned size; | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
struct FsFile : FsNode { | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
struct FsDir : FsNode { | 
				
			|||
    FsDir *parent; | 
				
			|||
    map<string, FsNode *> 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); | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
unsigned calc_size(FsDir &dir) | 
				
			|||
{ | 
				
			|||
    unsigned 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 { | 
				
			|||
                unsigned size = stoi(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; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
unsigned p1(const FsDir &dir) | 
				
			|||
{ | 
				
			|||
    unsigned 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; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
unsigned p2(const FsDir &dir, unsigned target = 0) | 
				
			|||
{ | 
				
			|||
    if (!target) target = dir.size - 40000000; | 
				
			|||
 | 
				
			|||
    unsigned smallest = 30000000; | 
				
			|||
    if (dir.size >= target && dir.size < smallest) smallest = dir.size; | 
				
			|||
 | 
				
			|||
    for (auto e : dir.entries) { | 
				
			|||
        FsNode *node = e.second; | 
				
			|||
        if (node->type == NODE_DIR) { | 
				
			|||
            unsigned size = p2(*(FsDir *)node, target); | 
				
			|||
            if (size >= target && size < smallest) smallest = size; | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
    return smallest; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void free_input(FsDir &dir) | 
				
			|||
{ | 
				
			|||
    for (auto e : dir.entries) { | 
				
			|||
        FsNode *node = e.second; | 
				
			|||
        if (node->type == NODE_DIR) { | 
				
			|||
            FsDir *dir = (FsDir *)node; | 
				
			|||
            free_input(*dir); | 
				
			|||
            delete dir; | 
				
			|||
        } else if (node->type == NODE_FILE) { | 
				
			|||
            FsFile *file = (FsFile *)node; | 
				
			|||
            delete file; | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
int main() | 
				
			|||
{ | 
				
			|||
    auto input = parse(); | 
				
			|||
    cout << p1(input) << endl; | 
				
			|||
    cout << p2(input) << endl; | 
				
			|||
    free_input(input); | 
				
			|||
} | 
				
			|||
								
									
										File diff suppressed because it is too large
									
								
							
						
					@ -0,0 +1,2 @@ | 
				
			|||
1783610 | 
				
			|||
4370655 | 
				
			|||
					Loading…
					
					
				
		Reference in new issue