import fs from 'node:fs' function main(filename) { const file = fs.readFileSync(filename, { encoding: "utf-8" }, data => data).split('\n') const set = new Map(file.filter(line => line != '').map(str => str.split(':'))) let computer = new Computer() computer.program = set.get('Program').trim().split(',').map(Number) computer.registers.A = parseInt(set.get('Register A').trim()) computer.registers.B = parseInt(set.get('Register B').trim()) computer.registers.C = parseInt(set.get('Register C').trim()) computer.run(computer.program) } class Computer { constructor() { this.registers = { A: 0, B: 0, C: 0 } this.output = [] this.program = [] this.ip = 0 this.ops = 0 } getCombo(operand) { switch (operand) { case 4: return this.registers.A; case 5: return this.registers.B; case 6: return this.registers.C; case 7: return 0 } return operand } doOperations(opcode, operand) { this.ops++ switch (opcode) { case 0: this.registers.A = Math.floor(this.registers.A / Math.pow(2, this.getCombo(operand))) break // division by operand^2 case 1: this.registers.B = (this.registers.B ^ operand); break // bitwise XOR literal operand case 2: this.registers.B = (this.getCombo(operand) % 8); break //mod8 combo operand case 3: if (this.registers.A !== 0) { this.ip = operand return true } break case 4: this.registers.B = (this.registers.B ^ this.registers.C); break // bitwise XOR case 5: this.output.push((this.getCombo(operand) % 8)); break // output combo case 6: this.registers.B = Math.floor(this.registers.A / Math.pow(2, this.getCombo(operand))); break case 7: this.registers.C = Math.floor(this.registers.A / Math.pow(2, this.getCombo(operand))); break default: break } return false } run(program) { while (this.ip < program.length) { let opcode = program[this.ip] let operand = program[this.ip + 1] const jumped = this.doOperations(opcode, operand) if (!jumped) this.ip += 2 } console.log(this) console.log(this.output.join(",")) } } main('input.txt')