advent-of-code

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

commit e6b3b458e6ab8decdef578d6974c0ad85a2c0289
parent 42b3eff19727f550ac0880d36bfa97fe09b9553f
Author: finwo <finwo@pm.me>
Date:   Sun, 11 Dec 2022 16:51:22 +0100

2022/11 solution

Diffstat:
A2022/day-11/index.js | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2022/day-11/sample | 28++++++++++++++++++++++++++++
2 files changed, 135 insertions(+), 0 deletions(-)

diff --git a/2022/day-11/index.js b/2022/day-11/index.js @@ -0,0 +1,107 @@ +const fs = require('fs'); +const through = require('through2'); +const line_for_line = require('../common/line-for-line'); + +String.prototype.startsWith = function(subject) { + return this.substr(0, subject.length) === subject; +}; + +const monkeys = []; + +fs.createReadStream('input') + .pipe(line_for_line()) + + // Turn into paragraphs + .pipe(through(function(line, enc, cb) { + line = line.toString(); + this.buffer = this.buffer || []; + + // Emit paragraph on empty line + if (!line.length) { + this.push(this.buffer.join('\n')); + this.buffer = []; + return cb(); + } + + // Add line to buffer + this.buffer.push(line); + cb(); + })) + + // Prase paragraph + .pipe(through(function(paragraph, enc, cb) { + paragraph = paragraph.toString(); + + const lines = paragraph + .split('\n') + .map(str => str.replace(/^\s+|\s+$/g, '')) + .map(str => str.split(':').map(s => s.replace(/^\s+|\s+$/g, ''))) + ; + + const monkey = {inspects: 0}; + + lines.forEach(line => { + const [name, value] = line; + if (name.startsWith("Monkey")) { + monkey.id = parseInt(name.split(' ').pop()); + } else if (name == 'Starting items') { + monkey.items = value.split(', ').map(v => BigInt(v)); + } else if (name == 'Test') { + monkey.test = BigInt(value.split(' ').pop()); + } else if (name == 'If true') { + monkey.resolve = parseInt(value.split(' ').pop()); + } else if (name == 'If false') { + monkey.reject = parseInt(value.split(' ').pop()); + } else if (name == 'Operation') { + monkey.operation = Function('old', `return ${value.substr(6).replace(/(\d+)/, '$1n')};`); + } + }); + + monkeys.push(monkey); + cb(); + })) + + .on('finish', () => { + monkeys.sort((a, b) => a.id - b.id); + console.log({ monkeys }); + + const pod = monkeys + .map(m => m.test) + .reduce((r,a) => r*a, 1n); + + for(let i=0; i<10000; i++) { + + for(let j=0; j<monkeys.length; j++) { + // for(const monkey of monkeys) { + // process.stdout.write(`Monkey ${monkey.id}:\n`); + monkeys[j].inspects += monkeys[j].items.length; + + const test = (wl) => + wl % monkeys[j].test == 0n ? monkeys[j].resolve : monkeys[j].reject; + + while(monkeys[j].items.length) { + const item = monkeys[j].items.shift(); + let _new = monkeys[j].operation(item) % pod; + monkeys[test(_new)].items.push(_new); + } + process.stdout.write(`Monkey ${monkeys[j].id} inspected items ${monkeys[j].inspects} times.\n`); + } + process.stdout.write(`Round ${i} finished\n\n`); + } + + // // Find the most active monkeys + // for(const monkey of monkeys) { + // process.stdout.write(`Monkey ${monkey.id} inspected items ${monkey.inspects} times.\n`); + // } + + monkeys.sort((a, b) => { + const x = b.inspects - a.inspects; + if (x < 0n) return -1; + if (x > 0n) return 1; + return 0; + }); + + process.stdout.write(`\nMonkey business: ${monkeys[0].inspects} * ${monkeys[1].inspects} = ${monkeys[0].inspects * monkeys[1].inspects}\n`); + + console.log('finish'); + }); diff --git a/2022/day-11/sample b/2022/day-11/sample @@ -0,0 +1,28 @@ +Monkey 0: + Starting items: 79, 98 + Operation: new = old * 19 + Test: divisible by 23 + If true: throw to monkey 2 + If false: throw to monkey 3 + +Monkey 1: + Starting items: 54, 65, 75, 74 + Operation: new = old + 6 + Test: divisible by 19 + If true: throw to monkey 2 + If false: throw to monkey 0 + +Monkey 2: + Starting items: 79, 60, 97 + Operation: new = old * old + Test: divisible by 13 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 74 + Operation: new = old + 3 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 1 +