master
Benjamin Kraft 2 years ago
parent bd8ceeda1a
commit 9cc732f746
  1. 126
      src/days/07/Day07.cpp
  2. 28
      src/days/07/Day07.h

@ -1,9 +1,131 @@
#include "Day07.h"
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() {
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;
}

@ -2,9 +2,37 @@
#include "../../Day.h"
struct Dir;
struct Item {
Item(string name, Dir* parent) : name(name), parent(parent){};
string name;
Dir* parent;
virtual uint64_t getSize();
};
struct Dir : Item {
Dir(string name, Dir* parent) : Item(name, parent) {}
set<Item*> items;
Dir* findRoot();
uint64_t getSize();
set<Dir*> getDirs();
set<Dir*> getAllDirsBelowSize(uint64_t maxSize);
set<Dir*> getAllDirsAboveSize(uint64_t minSize);
};
struct File : Item {
File(string name, Dir* parent, uint64_t size) : Item(name, parent), size(size) {}
uint64_t size;
uint64_t getSize();
};
class Day07 : public Day {
protected:
Result Task1() override;
Result Task2() override;
Dir* parseTree();
};
Loading…
Cancel
Save