advent-of-code

Entries to advent of code, multiple years
git clone git://git.finwo.net/misc/advent-of-code
Log | Files | Refs

commit c17cc3ebd4a2040f9643bc15433edfcf37dece61
parent b7f551c0c23d3769430e1f36de8b8afd60872197
Author: finwo <finwo@pm.me>
Date:   Wed,  7 Dec 2022 11:26:06 +0100

2022/07 solution

Diffstat:
A2022/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 + + });