Browse Source

Day 11

master
Ben Ashton 1 year ago
parent
commit
54caefb22e
  1. 55
      11/input
  2. 136
      11/solution.mjs

55
11/input

@ -0,0 +1,55 @@
Monkey 0:
Starting items: 54, 98, 50, 94, 69, 62, 53, 85
Operation: new = old * 13
Test: divisible by 3
If true: throw to monkey 2
If false: throw to monkey 1
Monkey 1:
Starting items: 71, 55, 82
Operation: new = old + 2
Test: divisible by 13
If true: throw to monkey 7
If false: throw to monkey 2
Monkey 2:
Starting items: 77, 73, 86, 72, 87
Operation: new = old + 8
Test: divisible by 19
If true: throw to monkey 4
If false: throw to monkey 7
Monkey 3:
Starting items: 97, 91
Operation: new = old + 1
Test: divisible by 17
If true: throw to monkey 6
If false: throw to monkey 5
Monkey 4:
Starting items: 78, 97, 51, 85, 66, 63, 62
Operation: new = old * 17
Test: divisible by 5
If true: throw to monkey 6
If false: throw to monkey 3
Monkey 5:
Starting items: 88
Operation: new = old + 3
Test: divisible by 7
If true: throw to monkey 1
If false: throw to monkey 0
Monkey 6:
Starting items: 87, 57, 63, 86, 87, 53
Operation: new = old * old
Test: divisible by 11
If true: throw to monkey 5
If false: throw to monkey 0
Monkey 7:
Starting items: 73, 59, 82, 65
Operation: new = old + 6
Test: divisible by 2
If true: throw to monkey 4
If false: throw to monkey 3

136
11/solution.mjs

@ -0,0 +1,136 @@
import { readFileSync } from 'node:fs';
const input = readFileSync('input', 'utf-8');
class Item {
constructor(initialWorryLevel) {
this.worryLevel = initialWorryLevel;
}
}
class Monkey {
constructor(monkeys, number, items, operation, test, afterInspectHook) {
this.monkeys = monkeys;
this.number = number;
this.items = items;
this.operation = operation;
this.test = test;
this.afterInspectHook = afterInspectHook;
this.inspectCount = 0;
}
processItem() {
const item = this.items.shift();
item.worryLevel = this.operation(item.worryLevel);
this.inspectCount++;
this.afterInspectHook?.(item);
const passToMonkey = this.monkeys.get(this.test.test(item.worryLevel));
passToMonkey.items.push(item);
}
processItems() {
while (this.items.length) {
this.processItem();
}
}
}
class Test {
constructor(divisibleBy, trueCondition, falseCondition) {
this.divisibleBy = divisibleBy;
this.trueCondition = trueCondition;
this.falseCondition = falseCondition;
}
test(worryLevel) {
return worryLevel % this.divisibleBy === 0 ?
this.trueCondition :
this.falseCondition;
}
}
export function getMonkeys(afterInspectHook) {
const monkeys = new Map();
input
.split('\n\n')
.filter(monkeyData => /\S/.test(monkeyData))
.forEach(monkeyData => {
let number;
let items;
let operation;
let test;
monkeyData
.trim()
.split(/\n (?=\S)/)
.forEach(data => {
if (data.startsWith('Monkey')) {
number = parseInt(data.match(/\d+/)[0]);
} else if (data.startsWith('Starting items')) {
items = data
.split(': ', 2)[1]
.split(', ')
.map(worryLevel => new Item(parseInt(worryLevel)));
} else if (data.startsWith('Operation')) {
operation = new Function(
'old',
`return ${data.split('new = ', 2)[1].trim()}`
);
} else if (data.startsWith('Test')) {
const divisibleBy = parseInt(data.match(/divisible by (\d+)/)[1]);
const trueCondition = parseInt(data.match(/true[^\n]*(\d+)/)[1]);
const falseCondition = parseInt(data.match(/false[^\n]*(\d+)/)[1]);
test = new Test(divisibleBy, trueCondition, falseCondition);
}
});
monkeys.set(
number,
new Monkey(monkeys, number, items, operation, test, afterInspectHook)
);
});
return monkeys;
}
export function simulateRounds(monkeys, nRounds) {
for (let round = 0; round < nRounds; round++) {
for (const number of [...monkeys.keys()].sort()) {
const monkey = monkeys.get(number);
monkey.processItems();
}
}
}
function calculateMonkeyBusinessLevel(monkeys) {
return [...monkeys.values()]
.sort((m1, m2) => m2.inspectCount - m1.inspectCount)
.slice(0, 2)
.map(monkey => monkey.inspectCount)
.reduce((total, monkeyBusiness) => total * monkeyBusiness);
}
let monkeys;
let monkeyBusinessLevel;
monkeys = getMonkeys(
item => item.worryLevel = Math.floor(item.worryLevel / 3)
);
simulateRounds(monkeys, 20);
monkeyBusinessLevel = calculateMonkeyBusinessLevel(monkeys);
console.log(
`Level of monkey business after 20 rounds: ${monkeyBusinessLevel}`
);
monkeys = getMonkeys(item => {
const commonMultiple = [...monkeys.values()]
.map(monkey => monkey.test.divisibleBy)
.reduce((total, divisibleBy) => total * divisibleBy);
// Reduce item by commonMultiple whenever it exceeds that value
return item.worryLevel = item.worryLevel % commonMultiple;
});
simulateRounds(monkeys, 10000);
monkeyBusinessLevel = calculateMonkeyBusinessLevel(monkeys);
console.log(
`Level of monkey business after 10000 rounds: ${monkeyBusinessLevel}`
);
Loading…
Cancel
Save