const fs = require("fs"); const input = fs.readFileSync("input", "utf-8").trim().split("\n"); function main() { // original mask string let sum = 0n; let mask = null; const memory = []; for (const line of input) { if (line.startsWith("mask")) { mask = line.slice(7); } else { const sourceAddress = BigInt(parseInt(line.slice(4))); const num = BigInt(parseInt(line.split(" = ")[1])); const addresses = apply(sourceAddress, mask); for (const address of addresses) { if (typeof memory[address] !== "undefined") { sum -= memory[address]; } memory[address] = num; sum += num; } // debug(sourceAddress, mask, addresses); } } console.log("Fill memory done"); console.log("Solution:"); console.log(sum.toString()); } function debug(address, mask, addresses) { console.log("=".repeat(18), " DEBUG ", "=".repeat(18)); console.log(`address: ${numToBin(address)} (decimal ${address})`); console.log(`mask: ${mask}`); console.log(`result: `); for (const address of addresses) { console.log(`${numToBin(address)} (decimal ${address})`); } } function numToBin(num) { return num.toString(2).padStart(36, "0"); } function binToNum(bin) { return BigInt(parseInt(bin, 2)); } function apply(address, mask) { address = address | binToNum(mask.replaceAll("X", 0)); address = numToBin(address); let addresses = [""]; for (let i = 0; i < address.length; i++) { const bit = address[i]; const maskBit = mask[i]; if (maskBit === "X") { const zeroConcated = addresses.map((adr) => adr + "0"); const oneConcated = addresses.map((adr) => adr + "1"); addresses = [...zeroConcated, ...oneConcated]; } else { addresses = addresses.map((adr) => adr + bit); } } return addresses.map(binToNum); } main();