// Reads wires into an array then calls fn(). function readFile(file, fn) { require('readline').createInterface({ input: require('fs').createReadStream(file) }) .on('line', function (line) { var pieces = line.split(' -> '); wires[pieces[1]] = pieces[0]; }) .on('close', fn); } var wires = {}, calculated = {}, mask = 65535; var ops = { AND: function(a, b) { return a & b; }, OR: function (a, b) { return a | b; }, XOR: function (a, b) { return a ^ b; }, NOT: function (a) { return ~ a; }, LSHIFT: function (a, b) { return a << b; }, RSHIFT: function (a, b) { return a >> b; } }; // Recursively calculate the signal to this wire. function calculate(wire) { if (!isNaN(wire)) return parseInt(wire); if (calculated[wire]) return calculated[wire]; var input = wires[wire].split(' '), length = input.length; // Note: inputs must only be strings. if (length === 1) calculated[wire] = calculate(input[0]); else if (length === 2) calculated[wire] = ops.AND(ops[input[0]](calculate(input[1])), mask); else if (length === 3) calculated[wire] = ops.AND(ops[input[1]](calculate(input[0]), calculate(input[2])), mask); return calculated[wire]; } // Accept wire and file as arguments. Can also use "all" instead of a wire. var wire = process.argv[2] ? process.argv[2] : 'a'; var file = process.argv[3] ? process.argv[3] : 'day7_input'; readFile(file, function() { if (wire === 'all') { Object.keys(wires).map(calculate); console.log(calculated); } else { calculate(wire); console.log(calculated[wire]) } });