Advent of Code 2022 - Day 11: Monkey in the Middle Solution
Math and modulo operationPart 1
Purely adhoc
Implementation
1const fs = require("fs")23const readData = () => {4 const data = fs5 .readFileSync("./input", "utf-8")6 .split(/\r?\n/)7 .filter(Boolean)89 const monkeys = {}1011 for (let i = 0; i < data.length; i += 6) {12 const monkeyNumber = i / 613 monkeys[monkeyNumber] = {}14 monkeys[monkeyNumber].items = data[i + 1]15 .replace("Starting items: ", "")16 .trim()17 .replace(/,/g, "")18 .split(" ")19 .map(Number)2021 monkeys[monkeyNumber].op = (() => {22 const [operator, operand2] = data[i + 2]23 .replace("Operation: new = old ", "")24 .trim()25 .split(" ")2627 const isMirror = operand2 === "old"2829 return {30 "+": (operand, isMirror) => x => x + (isMirror ? x : operand),31 "-": (operand, isMirror) => x => x - (isMirror ? x : operand),32 "*": (operand, isMirror) => x => x * (isMirror ? x : operand),33 "/": (operand, isMirror) => x => x / (isMirror ? x : operand),34 }[operator](+operand2, isMirror)35 })()3637 monkeys[monkeyNumber].test = (() => {38 const divisibleBy = +data[i + 3].replace("Test: divisible by ", "").trim()39 const destMonkeyIfTrue = +data[i + 4]40 .replace("If true: throw to monkey ", "")41 .trim()42 const destMonkeyIfFalse = +data[i + 5]43 .replace("If false: throw to monkey ", "")44 .trim()4546 return {47 fn: x => x % divisibleBy === 0,48 destMonkeys: [destMonkeyIfFalse, destMonkeyIfTrue],49 }50 })()5152 monkeys[monkeyNumber].itemsInspectedTimes = 053 }5455 return Object.values(monkeys)56}5758const main = () => {59 const monkeys = readData()6061 let numberOfRounds = 206263 while (numberOfRounds--) {64 for (const [monkeyNo, monkey] of Object.entries(monkeys)) {65 for (let itemIndex = 0; itemIndex < monkey.items.length; itemIndex++) {66 const item = monkey.items[itemIndex]67 let worryLevel = monkey.op(item)68 worryLevel = Math.floor(worryLevel / 3)69 const destMonkey = monkey.test.destMonkeys[+monkey.test.fn(worryLevel)]70 monkeys[monkeyNo].items.splice(itemIndex, 1)71 itemIndex--72 monkeys[monkeyNo].itemsInspectedTimes++73 monkeys[destMonkey].items.push(worryLevel)74 }75 }76 }7778 const res = monkeys79 .map(({ itemsInspectedTimes }) => itemsInspectedTimes)80 .sort((a, b) => b - a)81 .slice(0, 2)82 .reduce((acc, el) => acc * el, 1)8384 console.log(res)85}8687main()
Part 2
Use modulo operation to avoid number explosion (BigInt)
I'm suck at math so I borrowed the solution and leave some others' comments as references below:
Implementation
1const fs = require("fs")23const readData = () => {4 const data = fs5 .readFileSync("./input", "utf-8")6 .split(/\r?\n/)7 .filter(Boolean)89 const monkeys = {}1011 for (let i = 0; i < data.length; i += 6) {12 const monkeyNumber = i / 613 monkeys[monkeyNumber] = {}14 monkeys[monkeyNumber].items = data[i + 1]15 .replace("Starting items: ", "")16 .trim()17 .replace(/,/g, "")18 .split(" ")19 .map(Number)2021 monkeys[monkeyNumber].op = (() => {22 const [operator, operand2] = data[i + 2]23 .replace("Operation: new = old ", "")24 .trim()25 .split(" ")2627 const isMirror = operand2 === "old"2829 return {30 "+": (operand, isMirror) => x => x + (isMirror ? x : operand),31 "-": (operand, isMirror) => x => x - (isMirror ? x : operand),32 "*": (operand, isMirror) => x => x * (isMirror ? x : operand),33 "/": (operand, isMirror) => x => x / (isMirror ? x : operand),34 }[operator](+operand2, isMirror)35 })()3637 monkeys[monkeyNumber].test = (() => {38 const divisibleBy = +data[i + 3].replace("Test: divisible by ", "").trim()39 const destMonkeyIfTrue = +data[i + 4]40 .replace("If true: throw to monkey ", "")41 .trim()42 const destMonkeyIfFalse = +data[i + 5]43 .replace("If false: throw to monkey ", "")44 .trim()4546 return {47 divisibleBy,48 fn: x => x % divisibleBy === 0,49 destMonkeys: [destMonkeyIfFalse, destMonkeyIfTrue],50 }51 })()5253 monkeys[monkeyNumber].itemsInspectedTimes = 054 }5556 return Object.values(monkeys)57}5859const main = () => {60 const monkeys = readData()6162 let numberOfRounds = 100006364 const modulo = monkeys65 .map(({ test: { divisibleBy } }) => divisibleBy)66 .reduce((acc, el) => acc * el, 1)6768 while (numberOfRounds--) {69 for (const [monkeyNo, monkey] of Object.entries(monkeys)) {70 monkey.itemsInspectedTimes += monkey.items.length71 for (let itemIndex = 0; itemIndex < monkey.items.length; itemIndex++) {72 const item = monkey.items[itemIndex]73 let worryLevel = monkey.op(item)74 worryLevel = worryLevel % modulo75 const destMonkey = monkey.test.destMonkeys[+monkey.test.fn(worryLevel)]76 monkeys[monkeyNo].items.splice(itemIndex, 1)77 itemIndex--78 monkeys[destMonkey].items.push(worryLevel)79 }80 }81 }8283 const res = monkeys84 .map(({ itemsInspectedTimes }) => itemsInspectedTimes)85 .sort((a, b) => b - a)86 .slice(0, 2)87 .reduce((acc, el) => acc * el, 1)8889 console.log(res)90}9192main()
References
Comments
Loading comments...
Tags
adventofcode
math
Apply and earn a $2,500 bonus once you're hired on your first job!
Clients from the Fortune 500 to Silicon Valley startups
Choose your own rate, get paid on time
From hourly, part-time, to full-time positions
Flexible remote working environment
A lot of open JavaScript jobs!!
Fact corner: Referred talent are 5x more likely to pass the Toptal screening process than the average applicant.
Still hesitate? Read HoningJS author's guide on dealing with Toptal interview process.