-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday7.cpp
More file actions
132 lines (112 loc) · 3.79 KB
/
Copy pathday7.cpp
File metadata and controls
132 lines (112 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#define LOG(x) std::cout << x << std::endl;
const int SIZE_LIMIT = 100000;
const int DISK_SPACE = 70000000;
const int UPDATE_SIZE = 30000000;
const std::string inputFilePath = "inputs/day7.txt";
struct File{
std::string name;
int size;
};
struct Directory{
std::string name;
int size;
std::vector<Directory*> subDirs;
std::vector<File> files;
Directory* parent;
~Directory(){
parent = nullptr;
for(int i=0; i < subDirs.size();i++){
delete subDirs[i];
}
}
};
Directory* findDirToDelete(Directory* currentDir, const int spaceNeeded){
// Set current dir as best fit if it has enough size
Directory* bestFit = nullptr;
if (currentDir->size >= spaceNeeded){
bestFit = currentDir;
}
// Compare best fit with the dir children's
for(int i=0; i < (currentDir->subDirs).size();i++){
Directory* currentChildBestFit = findDirToDelete(currentDir->subDirs[i], spaceNeeded);
if (currentChildBestFit && (currentChildBestFit->size < bestFit->size)){
bestFit = currentChildBestFit;
}
}
return bestFit;
}
int DFSandSetSizes(Directory* currentDir){
for(int i=0; i < (currentDir->subDirs).size();i++){
currentDir->size += DFSandSetSizes(currentDir->subDirs[i]);
}
for(int i=0; i < (currentDir->files).size();i++){
currentDir->size += currentDir->files[i].size;
}
return currentDir->size;
}
int getSumOfAllDirsWithinSizeLimit(Directory* currentDir){
int sum = 0;
for (int i = 0; i < (currentDir->subDirs).size(); i++){
sum += getSumOfAllDirsWithinSizeLimit(currentDir->subDirs[i]);
}
if (currentDir->size <= SIZE_LIMIT){
return sum + currentDir->size;
}
else{
return sum;
}
}
int main(){
std::ifstream ifs(inputFilePath, std::ifstream::in);
std::string line;
// Skip first line "cd /"
std::getline(ifs, line);
Directory rootDir = {"/", 0, {}, {}};
Directory* currentDir = &rootDir;
while(std::getline(ifs, line)){
if(line[0] == '$'){ // User command
std::string command = line.substr(2, 2);
if (command == "cd")
{
std::string whereTo = line.substr(5);
if (whereTo == ".."){
currentDir = currentDir->parent;
}
else{
for(int i=0; i < currentDir->subDirs.size();i++){
if (currentDir->subDirs[i]->name == whereTo){
currentDir = currentDir->subDirs[i];
break;
}
}
}
}
}
else { // We're listing files after the 'ls' command has been used
const std::string dirOrSize = line.substr(0, line.find(" "));
const std::string name = line.substr(line.find(" ") + 1);
int size = 0;
if(dirOrSize == "dir"){
Directory* newDir = new Directory{name, size, {}, {} ,currentDir};
currentDir->subDirs.push_back(newDir);
} else{ // file
size = std::stoi(dirOrSize);
File newFile = {name, size};
currentDir->files.push_back(newFile);
}
}
}
DFSandSetSizes(&rootDir); // Set sizes of every dir
// Ex1
const int ex1Output = getSumOfAllDirsWithinSizeLimit(&rootDir);
// Ex2
const int spaceNeeded = rootDir.size - (DISK_SPACE - UPDATE_SIZE);
const Directory* bestDirToDelete = findDirToDelete(&rootDir, spaceNeeded);
std::cout << "--Ex1 Output: " << ex1Output << std::endl;
std::cout << "--Ex2 Output: " << bestDirToDelete->size << std::endl;
return 0;
}