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.
Previous Post
Advent of Code 2022 - Day 10: Cathode-Ray Tube
A creative challenge