commit c17cc3ebd4a2040f9643bc15433edfcf37dece61
parent b7f551c0c23d3769430e1f36de8b8afd60872197
Author: finwo <finwo@pm.me>
Date: Wed, 7 Dec 2022 11:26:06 +0100
2022/07 solution
Diffstat:
| A | 2022/day-07/index.js | | | 108 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 108 insertions(+), 0 deletions(-)
diff --git a/2022/day-07/index.js b/2022/day-07/index.js
@@ -0,0 +1,108 @@
+const fs = require('fs');
+const through = require('through2');
+const line_for_line = require('../common/line-for-line');
+
+let pwd = [];
+let vfs = {};
+const size = Symbol('size');
+const dirs = {'/': 0};
+
+let totalsize = 70000000;
+
+function set(sub, path, value) {
+ // console.log('set', { sub, path, value });
+ path = path.slice();
+ const last = path.pop();
+ while(path.length) {
+ const token = path.shift();
+ sub = sub[token] = sub[token] || {};
+ }
+ sub[last] = value;
+}
+function get(sub, path) {
+ path = path.slice();
+ while(path.length) sub = sub[path.shift()];
+ return sub;
+}
+const sum = (r, a) => r + a;
+
+fs.createReadStream('input')
+ .pipe(line_for_line())
+
+ // Build directory structure
+ .pipe(through(function(line, enc, cb) {
+ line = line.toString();
+ process.stdout.write(`${pwd.join('/')}> ${line}\n`);
+ const [type, ...args] = line.split(' ');
+
+ if (!isNaN(type)) {
+ // File marker
+ const p = [...pwd, args[0]].join('/');
+ vfs[p] = parseInt(type);
+ } else if (type == 'dir') {
+ // Dir marker
+ const p = [...pwd, args[0]].join('/');
+ dirs[p] = 0;
+ } else if (type == '$') {
+ // Command marker
+ const cmd = args.shift();
+ switch(cmd) {
+ case 'cd':
+ if (args[0] === '..') pwd.pop();
+ else if (args[0] == '/') pwd = [];
+ else pwd.push(args[0]);
+ break;
+ default:
+ break;
+ }
+ } else {
+ throw new Error(`Unknown type: ${type}`);
+ }
+
+ // console.log(JSON.stringify({ type, args, vfs }, null, 2));
+ cb();
+ }))
+
+ // Actual tasks
+ .on('finish', () => {
+ // done
+
+ // Calculate size independently for each directory
+ for(let dir in dirs) {
+ if (!dirs.hasOwnProperty(dir)) continue;
+ if (dir == '/') {
+ dirs[dir] = Object.values(vfs).reduce((r,a)=>r+a, 0);
+ continue;
+ }
+ dir = dir + '/'
+ dirs[dir] = Object.entries(vfs)
+ .filter(([name, size]) => name.substr(0, dir.length) == dir)
+ .map(([name, size]) => size)
+ .reduce((r,a)=>r+a,0);
+ }
+
+ // Sum + threshold
+ const threshold = 100000;
+ let sum = 0;
+ for(const size of Object.values(dirs)) {
+ if (size > threshold) continue;
+ sum += size;
+ }
+ console.log({ sum });
+
+ // Find smallest above threshold
+ let unusedSize = totalsize - dirs['/'];
+ let neededSize = 30000000;
+ let deleteSize = neededSize - unusedSize;
+ let selected = '/';
+ for(const [name, size] of Object.entries(dirs)) {
+ if (size < deleteSize) continue;
+ if (size >= dirs[selected]) continue;
+ selected = name;
+ }
+
+ console.log({unusedSize, selected, 'sz': dirs[selected]});
+
+ // START -- En
+
+ });