60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
import { join } from 'https://deno.land/std@0.167.0/path/mod.ts';
|
|
|
|
type Directory = { type: 'directory' };
|
|
type File = { type: 'file'; size: number };
|
|
type Tree = Record<string, Record<string, Directory | File>>;
|
|
|
|
function buildTree(shellLog: string): Tree {
|
|
const tree: Tree = {};
|
|
let curPath = '';
|
|
for (const line of shellLog.split('\n')) {
|
|
if (line.startsWith('$')) {
|
|
if (line === '$ ls') {
|
|
continue;
|
|
}
|
|
curPath = join(curPath, line.split(' ').at(-1)!);
|
|
tree[curPath] ??= {};
|
|
continue;
|
|
}
|
|
if (line.startsWith('dir')) {
|
|
const dirName = line.split(' ').at(-1)!;
|
|
tree[curPath][dirName] = {
|
|
type: 'directory',
|
|
};
|
|
continue;
|
|
}
|
|
// only option left is file
|
|
const [fileSize, fileName] = line.split(' ') as [string, string];
|
|
tree[curPath][fileName] = {
|
|
type: 'file',
|
|
size: parseInt(fileSize),
|
|
};
|
|
}
|
|
return tree;
|
|
}
|
|
|
|
function duRec(tree: Tree, entryPath = '/'): Record<string, number> {
|
|
let result: Record<string, number> = {};
|
|
let curSize = 0;
|
|
for (const [name, entry] of Object.entries(tree[entryPath as keyof typeof tree])) {
|
|
if (entry.type === 'directory') {
|
|
const newEntry = join(entryPath, name);
|
|
result = Object.assign(result, duRec(tree, newEntry)) as Record<string, number>;
|
|
curSize += result[newEntry];
|
|
} else curSize += entry.size;
|
|
}
|
|
result[entryPath] = curSize;
|
|
return result;
|
|
}
|
|
|
|
const input = Deno.readTextFileSync('./input.txt').trimEnd();
|
|
const tree = buildTree(input);
|
|
const dirSizes = Object.values(duRec(tree));
|
|
const p1 = dirSizes.filter((size) => (size <= 100000))
|
|
.reduce((prev, cur) => prev + cur, 0);
|
|
console.log('Solution Part 1:', p1);
|
|
dirSizes.sort((a, b) => a - b);
|
|
const free = 70000000 - dirSizes.at(-1)!;
|
|
const p2 = dirSizes.find((size) => (free + size) >= 30000000);
|
|
console.log('Solution Part 2:', p2);
|