AOC2022/src/07_NoSpaceLeftOnDevice/NoSpaceLeftOnDevice.ts

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);