For a description of this problem, please check the Advent of Code website.
Example Input:
Register A: 729Register B: 0Register C: 0Program: 0,1,5,4,3,0
Part 1 Solution:
const fs = require('fs');const input = fs.readFileSync('./example-input.txt', 'utf8').trim().split('\n');let initialA, initialB, initialC;let program = [];input.forEach(line => {if (line.startsWith('Register A:')) {initialA = parseInt(line.split(':')[1].trim(), 10);} else if (line.startsWith('Register B:')) {initialB = parseInt(line.split(':')[1].trim(), 10);} else if (line.startsWith('Register C:')) {initialC = parseInt(line.split(':')[1].trim(), 10);} else if (line.startsWith('Program:')) {program = line.split(':')[1].trim().split(',').map(Number);}});const mod = (n, m) => ((n % m) + m) % m;function executeProgram(A, B, C, program) {let instructionPointer = 0;const output = [];const getComboValue = (operand) => {if (operand <= 3) return operand;if (operand === 4) return A;if (operand === 5) return B;if (operand === 6) return C;throw new Error('Invalid combo operand');};while (instructionPointer < program.length) {const opcode = program[instructionPointer];const operand = program[instructionPointer + 1];let jumped = false;switch (opcode) {case 0: { // advA = Math.trunc(A / Math.pow(2, getComboValue(operand)));break;}case 1: { // bxlB = (B ^ operand) >>> 0;break;}case 2: { // bstB = mod(getComboValue(operand), 8);break;}case 3: { // jnzif (A !== 0) {instructionPointer = operand;jumped = true;}break;}case 4: { // bxcB = (B ^ C) >>> 0;break;}case 5: { // outoutput.push(mod(getComboValue(operand), 8));break;}case 6: { // bdvB = Math.trunc(A / Math.pow(2, getComboValue(operand)));break;}case 7: { // cdvC = Math.trunc(A / Math.pow(2, getComboValue(operand)));break;}default:throw new Error(`Invalid opcode: ${opcode}`);}if (!jumped) instructionPointer += 2;}return output.join(',');}const result = executeProgram(initialA, initialB, initialC, program);console.log(result);
Part 2 Solution:
const fs = require('fs');const input = fs.readFileSync('./example-input.txt', 'utf8').trim().split('\n');let initialA, initialB, initialC;let program = [];input.forEach(line => {if (line.startsWith('Register A:')) {initialA = parseInt(line.split(':')[1].trim(), 10);} else if (line.startsWith('Register B:')) {initialB = parseInt(line.split(':')[1].trim(), 10);} else if (line.startsWith('Register C:')) {initialC = parseInt(line.split(':')[1].trim(), 10);} else if (line.startsWith('Program:')) {program = line.split(':')[1].trim().split(',').map(Number);}});const mod = (n, m) => ((n % m) + m) % m;function executeProgram(A, B, C, program) {let instructionPointer = 0;const output = [];const getComboValue = (operand) => {if (operand <= 3) return operand;if (operand === 4) return A;if (operand === 5) return B;if (operand === 6) return C;throw new Error('Invalid combo operand');};while (instructionPointer < program.length) {const opcode = program[instructionPointer];const operand = program[instructionPointer + 1];let jumped = false;switch (opcode) {case 0: { // advA = Math.trunc(A / Math.pow(2, getComboValue(operand)));break;}case 1: { // bxlB = (B ^ operand) >>> 0;break;}case 2: { // bstB = mod(getComboValue(operand), 8);break;}case 3: { // jnzif (A !== 0) {instructionPointer = operand;jumped = true;}break;}case 4: { // bxcB = (B ^ C) >>> 0;break;}case 5: { // outoutput.push(mod(getComboValue(operand), 8));break;}case 6: { // bdvB = Math.trunc(A / Math.pow(2, getComboValue(operand)));break;}case 7: { // cdvC = Math.trunc(A / Math.pow(2, getComboValue(operand)));break;}default:throw new Error(`Invalid opcode: ${opcode}`);}if (!jumped) instructionPointer += 2;}return output.join(',');}function findLowestA(initialB, initialC, program) {const queue = [{ result: '', len: 0 }];while (queue.length) {const current = queue.shift();if (current.len === program.length) {return parseInt(current.result, 2);}const from = parseInt(current.result + '000', 2);const to = parseInt(current.result + '111', 2);const expectedOutput = program.slice((current.len + 1) * -1).join(',');for (let a = from; a <= to; a++) {const output = executeProgram(a, initialB, initialC, program);if (output === expectedOutput) {queue.push({ result: a.toString(2), len: current.len + 1 });}}}}const result = findLowestA(initialB, initialC, program);console.log(result);