76 lines
1.8 KiB
JavaScript
76 lines
1.8 KiB
JavaScript
import fs from "fs";
|
|
|
|
/**
|
|
* @param mask
|
|
* @param val
|
|
*/
|
|
function getValue(mask, val) {
|
|
const binaryVal = val.toString(2).padStart(mask.length, "0");
|
|
let valStr = "";
|
|
for (let i = 0; i < mask.length; i++) {
|
|
valStr += mask[i] === "X" ? binaryVal[i] : mask[i];
|
|
}
|
|
return parseInt(valStr, 2);
|
|
}
|
|
|
|
/**
|
|
* @param mask
|
|
*/
|
|
function getAllMasks(mask) {
|
|
if (!mask.includes("X")) return mask;
|
|
|
|
return [
|
|
getAllMasks(mask.replace("X", "0")),
|
|
getAllMasks(mask.replace("X", "1")),
|
|
].flat();
|
|
}
|
|
|
|
/**
|
|
* @param originalMask
|
|
* @param replacedMasks
|
|
* @param address
|
|
*/
|
|
function getDecodedAddresses(originalMask, replacedMasks, address) {
|
|
return replacedMasks.map((mask) => {
|
|
const binaryAddr = address.toString(2).padStart(mask.length, "0");
|
|
let addrStr = "";
|
|
for (let i = 0; i < mask.length; i++) {
|
|
addrStr += originalMask[i] === "0" ? binaryAddr[i] : mask[i];
|
|
}
|
|
|
|
return parseInt(addrStr, 2);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Main function for Puzzle B
|
|
*
|
|
* @param {string} data - Puzzle input as a single string.
|
|
*/
|
|
async function main(data) {
|
|
const instructions = data.split(/\r?\n/).map((line) => line.split(" = "));
|
|
let memory = {}
|
|
let originalMask
|
|
let replacedMasks
|
|
|
|
instructions.forEach(([op, args]) =>{
|
|
if(op==="mask") {
|
|
originalMask = args;
|
|
replacedMasks = getAllMasks(originalMask);
|
|
} else {
|
|
const originalAddress = parseInt(op.match(/mem\[(\d+)\]/)[1], 10)
|
|
const value = parseInt(args)
|
|
|
|
getDecodedAddresses(originalMask, replacedMasks, originalAddress).forEach((decodedAddress) => {
|
|
memory[decodedAddress] = value;
|
|
})
|
|
}
|
|
})
|
|
|
|
return Object.values(memory).reduce((cur, prev) => cur + prev, 0)
|
|
}
|
|
|
|
fs.readFile("input", (err, data) => {
|
|
if (err) throw err;
|
|
main(data.toString()).then(console.log).catch(console.error);
|
|
});
|