Ben Ashton
1 year ago
2 changed files with 1221 additions and 0 deletions
@ -0,0 +1,120 @@ |
|||||||
|
import { readFileSync } from 'node:fs'; |
||||||
|
|
||||||
|
const input = readFileSync('input', 'utf-8'); |
||||||
|
|
||||||
|
class Directory { |
||||||
|
constructor(parent, name) { |
||||||
|
this.parent = parent; |
||||||
|
this.name = name; |
||||||
|
this.contents = []; |
||||||
|
} |
||||||
|
|
||||||
|
getOrCreateSubdirectory(name) { |
||||||
|
let dir = this.contents.find(c => c.name === name); |
||||||
|
if (dir) { |
||||||
|
return dir; |
||||||
|
} |
||||||
|
dir = new Directory(this, name); |
||||||
|
this.contents.push(dir); |
||||||
|
return dir; |
||||||
|
} |
||||||
|
|
||||||
|
getSize() { |
||||||
|
return this.contents.reduce((size, entry) => { |
||||||
|
if (entry instanceof File) { |
||||||
|
return size + entry.size; |
||||||
|
} else { |
||||||
|
return size + entry.getSize(); |
||||||
|
} |
||||||
|
}, 0); |
||||||
|
} |
||||||
|
|
||||||
|
getRecursiveSubdirs() { |
||||||
|
const subdirs = []; |
||||||
|
|
||||||
|
for (const entry of this.contents) { |
||||||
|
if (entry instanceof Directory) { |
||||||
|
subdirs.push(entry); |
||||||
|
subdirs.push(...entry.getRecursiveSubdirs()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return subdirs; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class File { |
||||||
|
constructor(parent, name, size) { |
||||||
|
this.parent = parent; |
||||||
|
this.name = name; |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
let currentDirectory; |
||||||
|
let rootDirectory; |
||||||
|
|
||||||
|
for (const line of input.split('\n').filter(line => line)) { |
||||||
|
if (line.startsWith('$ ls')) { |
||||||
|
// ignore
|
||||||
|
} else if (line.startsWith('$ cd')) { |
||||||
|
const path = line.slice(5).trim(); |
||||||
|
|
||||||
|
if (path === '..') { |
||||||
|
currentDirectory = currentDirectory.parent; |
||||||
|
} else { |
||||||
|
if (!currentDirectory) { |
||||||
|
currentDirectory = new Directory(null, path); |
||||||
|
rootDirectory = currentDirectory; |
||||||
|
} else { |
||||||
|
currentDirectory = currentDirectory.getOrCreateSubdirectory(path); |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (line.startsWith('dir')) { |
||||||
|
const path = line.slice(4).trim(); |
||||||
|
currentDirectory.getOrCreateSubdirectory(path); |
||||||
|
} else { |
||||||
|
let [size, name] = line.split(' ', 2); |
||||||
|
size = parseInt(size); |
||||||
|
const file = new File(currentDirectory, name, size); |
||||||
|
currentDirectory.contents.push(file); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Sum of directories with size less than or equal to 100000
|
||||||
|
let totalSizeOfMatchingDirs = 0; |
||||||
|
|
||||||
|
for (const dir of rootDirectory.getRecursiveSubdirs()) { |
||||||
|
const size = dir.getSize(); |
||||||
|
if (size <= 100000) { |
||||||
|
totalSizeOfMatchingDirs += size; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
console.log(`Sum of directory sizes under 100000: ${totalSizeOfMatchingDirs}`); |
||||||
|
|
||||||
|
|
||||||
|
const totalDiskSpace = 70000000; |
||||||
|
const spaceNeeded = 30000000; |
||||||
|
const totalUsedSpace = rootDirectory.getSize(); |
||||||
|
|
||||||
|
const totalUnusedSpace = totalDiskSpace - totalUsedSpace; |
||||||
|
|
||||||
|
const spaceToFree = spaceNeeded - totalUnusedSpace; |
||||||
|
|
||||||
|
let sizeOfDirToDelete = rootDirectory.getSize(); |
||||||
|
for (const dir of rootDirectory.getRecursiveSubdirs()) { |
||||||
|
const size = dir.getSize(); |
||||||
|
|
||||||
|
if (size >= spaceToFree) { |
||||||
|
sizeOfDirToDelete = Math.min(sizeOfDirToDelete, size); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
console.log( |
||||||
|
`Delete directory of size ${sizeOfDirToDelete} to free ${spaceToFree}` |
||||||
|
); |
||||||
|
|
Loading…
Reference in new issue