77 lines
2.7 KiB
JavaScript
77 lines
2.7 KiB
JavaScript
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') |