Public
Edited
Jan 4, 2023
Insert cell
Insert cell
Insert cell
Insert cell
input = FileAttachment("input.txt").text();
Insert cell
function parseMonkeyBehavior(notes) {
// I tried to get around the big number issue with BigInt, but that wasn't big enough 🤷‍♂️. It's necessary to use modular arithmetic. See the function below.
return notes
.split("\n\n")
.map(n => {
const noteObject = {inspections: 0};
const note = n
.split("\n")
.slice(1);
noteObject.items = note[0].split(":")[1].split(",").map(i => BigInt(i.trim()));
const operation = note[1].split("= ")[1];
noteObject.operation = old => eval(`${operation}${isNaN(operation.split(" ").at(-1)) ? "" : "n"}`);
noteObject.test = {
divisible: BigInt(note[2].split("by ")[1]),
monkeyTrue: Number(note[3].split("monkey ")[1]),
monkeyFalse: Number(note[4].split("monkey ")[1])
};

return noteObject;
});
}
Insert cell
function parseMonkeyBehaviorMod(rawNotes) {
const notes = rawNotes
.split("\n\n")
.map(n => n.split("\n").slice(1));
// Due to numbers getting so big, it's necessary to use modular arithmetic.
// How convenient that all the divisors in the monkey tests are prime numbers! Let's multiply them together to find the least common multiple.
const modulo = notes.reduce((m, n) => m * Number(n[2].split("by ")[1]), 1);
return notes
.map(note => {
const noteObject = {inspections: 0};
noteObject.items = note[0].split(":")[1].split(",").map(i => Number(i.trim()));
const operation = note[1].split("= ")[1];
noteObject.operation = old => (eval(operation)) % modulo;
noteObject.test = {
divisible: Number(note[2].split("by ")[1]),
monkeyTrue: Number(note[3].split("monkey ")[1]),
monkeyFalse: Number(note[4].split("monkey ")[1])
};

return noteObject;
});
}
Insert cell
function calcMonkeyBusiness(mb, rounds = 1, relief = true) {
for (let i = 0; i < rounds; i++) {
for (const m of mb) {
for (const item of [...m.items]) {
const worry = relief ? m.operation(item) / 3n : m.operation(item);
if (worry % m.test.divisible === 0n) mb[m.test.monkeyTrue].items.push(worry);
else mb[m.test.monkeyFalse].items.push(worry);
m.items.shift()
m.inspections++;
}
}
}

return mb
// .sort((a, b) => b.inspections - a.inspections)
// .slice(0, 2)
// .reduce((product, m) => product * m.inspections, 1);
}
Insert cell
function calcMonkeyBusinessMod(mb, rounds = 1, relief = true) {
for (let i = 0; i < rounds; i++) {
for (const m of mb) {
for (const item of [...m.items]) {
const worry = relief ? Math.floor(m.operation(item) / 3) : m.operation(item);
if (worry % m.test.divisible === 0) mb[m.test.monkeyTrue].items.push(worry);
else mb[m.test.monkeyFalse].items.push(worry);
m.items.shift()
m.inspections++;
}
}
}

return mb
.sort((a, b) => b.inspections - a.inspections)
.slice(0, 2)
.reduce((product, m) => product * m.inspections, 1);
}
Insert cell
Insert cell
// A large number of rounds will take a looooooooong time to calculate with BigInt. BE AWARE!
// calcMonkeyBusiness(parseMonkeyBehavior(testInput), 100, false);
Insert cell
calcMonkeyBusinessMod(parseMonkeyBehaviorMod(input), 10000, false);
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more