mid-kid
2 years ago
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