diff --git a/src/days/07/Day07.cpp b/src/days/07/Day07.cpp
index d89165a..0d252f4 100644
--- a/src/days/07/Day07.cpp
+++ b/src/days/07/Day07.cpp
@@ -1,9 +1,131 @@
#include "Day07.h"
Result Day07::Task1() {
- return Day::Task1();
+ Dir* tree = parseTree();
+
+ set
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();
-}
\ No newline at end of file
+ Dir* tree = parseTree();
+
+ uint64_t toBeFreed = 30000000 - (70000000 - tree->getSize());
+
+ set dirsAbove = tree->getAllDirsAboveSize(toBeFreed);
+ set 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(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::getDirs() {
+ set dirs;
+ for (Item* item : items){
+ if (Dir* d = dynamic_cast(item))
+ dirs.insert(d);
+ }
+ return dirs;
+}
+
+set Dir::getAllDirsBelowSize(uint64_t maxSize) {
+ set result;
+
+ for (Dir* dir : getDirs()){
+ if (dir->getSize() <= maxSize)
+ result.insert(dir);
+ set sub = dir->getAllDirsBelowSize(maxSize);
+ result.insert(sub.begin(), sub.end());
+ }
+
+ return result;
+}
+
+set Dir::getAllDirsAboveSize(uint64_t minSize) {
+ set result;
+
+ for (Dir* dir : getDirs()){
+ if (dir->getSize() >= minSize)
+ result.insert(dir);
+ set sub = dir->getAllDirsAboveSize(minSize);
+ result.insert(sub.begin(), sub.end());
+ }
+
+ return result;
+}
+
+uint64_t File::getSize() {
+ return size;
+}
+
+uint64_t Item::getSize() {
+ return 0;
+}
diff --git a/src/days/07/Day07.h b/src/days/07/Day07.h
index 39f98fe..4bb7457 100644
--- a/src/days/07/Day07.h
+++ b/src/days/07/Day07.h
@@ -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- items;
+ Dir* findRoot();
+ uint64_t getSize();
+ set getDirs();
+ set getAllDirsBelowSize(uint64_t maxSize);
+ set 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();
};
\ No newline at end of file