parent
bd8ceeda1a
commit
9cc732f746
2 changed files with 153 additions and 3 deletions
@ -1,9 +1,131 @@ |
|||||||
#include "Day07.h" |
#include "Day07.h" |
||||||
|
|
||||||
Result Day07::Task1() { |
Result Day07::Task1() { |
||||||
return Day::Task1(); |
Dir* tree = parseTree(); |
||||||
|
|
||||||
|
set<Dir*> dirsBelow = tree->getAllDirsBelowSize(100000); |
||||||
|
uint64_t sum = accumulate(dirsBelow.begin(), dirsBelow.end(), 0, [](uint64_t s, Dir* dir){ |
||||||
|
return s + dir->getSize(); |
||||||
|
}); |
||||||
|
|
||||||
|
delete tree; |
||||||
|
return to_string(sum); |
||||||
} |
} |
||||||
|
|
||||||
Result Day07::Task2() { |
Result Day07::Task2() { |
||||||
return Day::Task2(); |
Dir* tree = parseTree(); |
||||||
} |
|
||||||
|
uint64_t toBeFreed = 30000000 - (70000000 - tree->getSize()); |
||||||
|
|
||||||
|
set<Dir*> dirsAbove = tree->getAllDirsAboveSize(toBeFreed); |
||||||
|
set<uint64_t> sizes; |
||||||
|
std::transform(dirsAbove.begin(), dirsAbove.end(), inserter(sizes, sizes.begin()), [](Dir* dir){ |
||||||
|
return dir->getSize(); |
||||||
|
}); |
||||||
|
uint64_t result = *std::min_element(sizes.begin(), sizes.end()); |
||||||
|
|
||||||
|
delete tree; |
||||||
|
return to_string(result); |
||||||
|
} |
||||||
|
|
||||||
|
Dir* Day07::parseTree() { |
||||||
|
Dir* tree = new Dir("/", nullptr); |
||||||
|
Dir* cwd = tree; |
||||||
|
|
||||||
|
auto pos = input.begin() + 1; |
||||||
|
while (pos < input.end()){ |
||||||
|
if (pos->starts_with('$')){ |
||||||
|
if (pos->substr(2, 2) == "ls"){ |
||||||
|
pos++; |
||||||
|
while (pos < input.end() && !pos->starts_with('$')){ |
||||||
|
if (pos->starts_with("dir")){ |
||||||
|
string name = pos->substr(4); |
||||||
|
cwd->items.insert(new Dir(name, cwd)); |
||||||
|
} else { |
||||||
|
size_t ws = pos->find(' '); |
||||||
|
uint64_t size = stoi(pos->substr(0, ws)); |
||||||
|
string name = pos->substr(ws + 1); |
||||||
|
cwd->items.insert(new File(name, cwd, size)); |
||||||
|
} |
||||||
|
pos++; |
||||||
|
} |
||||||
|
continue; |
||||||
|
} |
||||||
|
if (pos->substr(2, 2) == "cd"){ |
||||||
|
string name = pos->substr(5); |
||||||
|
if (name == ".."){ |
||||||
|
cwd = cwd->parent; |
||||||
|
} else if (name == "/"){ |
||||||
|
cwd = cwd->findRoot(); |
||||||
|
} else { |
||||||
|
for (Item* item : cwd->items){ |
||||||
|
if (item->name == name){ |
||||||
|
if (Dir* d = dynamic_cast<Dir*>(item)){ |
||||||
|
cwd = d; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
pos++; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return tree; |
||||||
|
} |
||||||
|
|
||||||
|
Dir *Dir::findRoot() { |
||||||
|
if (name == "/") |
||||||
|
return this; |
||||||
|
return parent->findRoot(); |
||||||
|
} |
||||||
|
|
||||||
|
uint64_t Dir::getSize() { |
||||||
|
return accumulate(items.begin(), items.end(), 0, [](uint64_t s, Item* item){ |
||||||
|
return s + item->getSize(); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
set<Dir*> Dir::getDirs() { |
||||||
|
set<Dir*> dirs; |
||||||
|
for (Item* item : items){ |
||||||
|
if (Dir* d = dynamic_cast<Dir*>(item)) |
||||||
|
dirs.insert(d); |
||||||
|
} |
||||||
|
return dirs; |
||||||
|
} |
||||||
|
|
||||||
|
set<Dir*> Dir::getAllDirsBelowSize(uint64_t maxSize) { |
||||||
|
set<Dir*> result; |
||||||
|
|
||||||
|
for (Dir* dir : getDirs()){ |
||||||
|
if (dir->getSize() <= maxSize) |
||||||
|
result.insert(dir); |
||||||
|
set<Dir*> sub = dir->getAllDirsBelowSize(maxSize); |
||||||
|
result.insert(sub.begin(), sub.end()); |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
set<Dir *> Dir::getAllDirsAboveSize(uint64_t minSize) { |
||||||
|
set<Dir*> result; |
||||||
|
|
||||||
|
for (Dir* dir : getDirs()){ |
||||||
|
if (dir->getSize() >= minSize) |
||||||
|
result.insert(dir); |
||||||
|
set<Dir*> sub = dir->getAllDirsAboveSize(minSize); |
||||||
|
result.insert(sub.begin(), sub.end()); |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
uint64_t File::getSize() { |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
uint64_t Item::getSize() { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
Loading…
Reference in new issue