126 lines
3.2 KiB
JavaScript
126 lines
3.2 KiB
JavaScript
import { readFileSync } from "fs";
|
|
|
|
class Folder {
|
|
constructor(path) {
|
|
this.path = path;
|
|
this.folders = {};
|
|
this.files = {};
|
|
}
|
|
|
|
addFolder(path, folderName) {
|
|
if(this.path === path) {
|
|
this.folders[folderName] = new Folder(`${path}${folderName}/`);
|
|
} else {
|
|
const newSubFolder = path.replace(this.path, '').split("/")[0];
|
|
this.folders[newSubFolder].addFolder(path, folderName);
|
|
}
|
|
}
|
|
|
|
addFile(path, fileName, fileSize) {
|
|
if(this.path === path) {
|
|
this.files[fileName] = fileSize;
|
|
} else {
|
|
const newSubFolder = path.replace(this.path, '').split("/")[0];
|
|
this.folders[newSubFolder].addFile(path, fileName, fileSize);
|
|
}
|
|
}
|
|
|
|
getCurrentDirectorySize() {
|
|
let totalSize = 0;
|
|
|
|
for(const [fileName, fileSize] of Object.entries(this.files)) {
|
|
totalSize += parseInt(fileSize)
|
|
}
|
|
|
|
for(const [folderName, folderObj] of Object.entries(this.folders)) {
|
|
totalSize += folderObj.getCurrentDirectorySize()
|
|
}
|
|
|
|
return totalSize;
|
|
}
|
|
}
|
|
|
|
const input = readFileSync("commands.txt", "utf-8");
|
|
|
|
let currentDir = "/";
|
|
let lastCommand = [];
|
|
|
|
const root = new Folder("/");
|
|
|
|
input.split('\n').forEach(line => {
|
|
if(line.startsWith("$")) {
|
|
lastCommand = line.split(" ");
|
|
lastCommand.shift();
|
|
|
|
if(lastCommand[0] === "cd" && lastCommand[1] !== ".." && lastCommand[1] !== "/") {
|
|
currentDir += `${lastCommand[1]}/`;
|
|
}
|
|
|
|
if(lastCommand[0] === "cd" && lastCommand[1] === "..") {
|
|
const tmp = currentDir.split("/")
|
|
tmp.shift();
|
|
tmp.pop();
|
|
tmp.pop();
|
|
currentDir = `/${tmp.join("/")}/`;
|
|
if(currentDir === "//") currentDir = "/"
|
|
}
|
|
} else { // output
|
|
const name = line.split(" ");
|
|
if(name[0] === "dir") {
|
|
root.addFolder(currentDir, name[1]);
|
|
} else {
|
|
root.addFile(currentDir, name[1], name[0]);
|
|
}
|
|
}
|
|
});
|
|
|
|
console.log("=== PART 1 ===");
|
|
|
|
function part1(currentFolders) {
|
|
let totalSize = 0;
|
|
|
|
for(const [folderName, folderObj] of Object.entries(currentFolders)) {
|
|
const a = folderObj.getCurrentDirectorySize();
|
|
if(a < 100_000) totalSize += a;
|
|
totalSize += part1(folderObj.folders)
|
|
}
|
|
|
|
return totalSize;
|
|
}
|
|
|
|
|
|
console.log(part1(root.folders))
|
|
|
|
console.log("=== PART 2 ===");
|
|
|
|
function part2(currentFolders) {
|
|
const arr = [];
|
|
|
|
for(const [folderName, folderObj] of Object.entries(currentFolders)) {
|
|
arr.push(...part2(folderObj.folders));
|
|
arr.push({
|
|
name: folderObj.path,
|
|
size: folderObj.getCurrentDirectorySize()
|
|
})
|
|
}
|
|
|
|
return arr;
|
|
}
|
|
|
|
const total = 70_000_000;
|
|
const required = 30_000_000;
|
|
|
|
let free = total - root.getCurrentDirectorySize();
|
|
let toDelete = required - free;
|
|
|
|
const part2Array = part2(root.folders);
|
|
|
|
part2Array.sort((a, b) => b.size - a.size);
|
|
|
|
let sizeOfSmallestDeletableDirectory = 0;
|
|
|
|
part2Array.forEach(folder => {
|
|
if(toDelete - folder.size < 0) sizeOfSmallestDeletableDirectory = folder.size;
|
|
});
|
|
|
|
console.log(sizeOfSmallestDeletableDirectory); |