import fs from "node:fs"; import { Temporal } from "@js-temporal/polyfill"; import { printTime } from "../util"; const data = fs.readFileSync("./inputs/input", "utf8"); let timer = Temporal.Now.instant(); console.log( "part one:", data .split("\n") .slice(0, -1) // remove empty trailing newline .reduce((total, line) => { let state = { char: "", multiplicand: "", multiplier: "", }; for (let index = 0; index < line.length; index++) { switch (true) { case "0123456789".includes(line[index]) && state.char === "(": state.multiplicand += line[index]; break; case "0123456789".includes(line[index]) && state.char === ",": state.multiplier += line[index]; break; case state.char === "(" && line[index] === "," && state.multiplicand !== "": state.char = line[index]; break; case line[index] === ")" && state.char === "," && state.multiplier !== "": total += parseInt(state.multiplicand, 10) * parseInt(state.multiplier, 10); state = { char: "", multiplicand: "", multiplier: "" }; break; case line[index] === "m" && state.char === "": case line[index] === "u" && state.char === "m": case line[index] === "l" && state.char === "u": case line[index] === "(" && state.char === "l": state.char = line[index]; break; default: state = { char: "", multiplicand: "", multiplier: "" }; break; } } return total; }, 0), printTime(Temporal.Now.instant().since(timer)) ); timer = Temporal.Now.instant(); console.log( "part two:", data .split("\n") .slice(0, -1) // remove empty trailing newline .reduce( (total, line) => { let state = { char: "", multiplicand: "", multiplier: "", on: total.on, }; for (let index = 0; index < line.length; index++) { switch (true) { case "0123456789".includes(line[index]) && state.char === "mul(": state.multiplicand += line[index]; break; case "0123456789".includes(line[index]) && state.char === ",": state.multiplier += line[index]; break; case state.char === "mul(" && line[index] === "," && state.multiplicand !== "": state.char = line[index]; break; case line[index] === ")" && state.char === "," && state.multiplier !== "": if (state.on) { total = { ...total, sum: (total.sum += parseInt(state.multiplicand, 10) * parseInt(state.multiplier, 10)), }; } state = { ...state, char: "", multiplicand: "", multiplier: "", }; break; case line[index] === ")" && state.char === "don't(": state = { char: "", multiplicand: "", multiplier: "", on: false }; break; case line[index] === ")" && state.char === "do(": state = { char: "", multiplicand: "", multiplier: "", on: true }; break; case line[index] === "m" && state.char === "": case line[index] === "u" && state.char === "m": case line[index] === "l" && state.char === "mu": case line[index] === "(" && state.char === "mul": case line[index] === "d" && state.char === "": case line[index] === "o" && state.char === "d": case line[index] === "n" && state.char === "do": case line[index] === "(" && state.char === "do": case line[index] === "'" && state.char === "don": case line[index] === "t" && state.char === "don'": case line[index] === "(" && state.char === "don't": state.char += line[index]; break; default: state = { ...state, char: "", multiplicand: "", multiplier: "", }; break; } } return { ...total, on: state.on }; }, { sum: 0, on: true } ).sum, printTime(Temporal.Now.instant().since(timer)) );