Advent of Code, Day 8: Handheld Halting
Go to Day 8 Challenge |
Go to index
I ran this code in the devtoolbar in Chrome, and the answers were simply outputted to the console.
Learn more about my solution.
Part I
"The boot code is represented as a text file with one instruction per line of text.
Each instruction consists of an operation (acc, jmp, or nop) and an argument (a signed
number like +4 or -20)."
ref
var instructions = document.getElementsByTagName('pre')[0].innerText.split('\n')
var accumulator = 0
var stepIndex = 0
var stepsCompleted = []
var processStep = (index) => {
var cmd = instructions[index]
if(!stepsCompleted.some(s => s.command === cmd && s.index === index)){
var iArray = cmd.match(/([a-z]{3})\s([-+0-9]+)/i)
if(iArray){
var instruction = { command: cmd, index, operation: iArray[1], argument: Number(iArray[2]) }
console.log(instruction)
switch (instruction.operation) {
case 'acc':
accumulator += instruction.argument
stepIndex += 1
break;
case 'jmp':
stepIndex += instruction.argument
break;
case 'nop':
default:
stepIndex += 1
break;
}
// debugger
stepsCompleted.push(instruction)
processStep(stepIndex)
}
}
}
processStep(stepIndex)
console.log(stepIndex, accumulator)
Part II
"Somewhere in the program, either a jmp is supposed to be a nop, or a nop is
supposed to be a jmp. (No acc instructions were harmed in the corruption of this boot code.)"
ref
var instructions = document.getElementsByTagName('pre')[0].innerText.trim().split('\n')
var accumulator = 0
var stepIndex = 0
var stepsCompleted = []
var swapped = []
var didSwap = false
var processStep = (index) => {
if(index < instructions.length) {
var cmd = instructions[index]
if(cmd) {
if(!stepsCompleted.some(s => s.command === cmd && s.index === index)){
var iArray = cmd.match(/([a-z]{3})\s([-+0-9]+)/i)
if(iArray){
var instruction = { command: cmd, index, operation: iArray[1], argument: Number(iArray[2]) }
stepsCompleted.push(instruction)
// console.log(instruction)
switch (instruction.operation) {
case 'acc':
accumulator += instruction.argument
stepIndex += 1
break;
case 'jmp':
if(!didSwap && !swapped.some(s => s.command === cmd && s.index === index)) {
// swap with nop, do nothing
// debugger
// console.log('swapped',instruction)
didSwap = true
swapped.push(instruction)
stepIndex += 1
} else {
stepIndex += instruction.argument
// console.log('not swapped',instruction)
}
break;
case 'nop':
if(!didSwap && !swapped.some(s => s.command === cmd && s.index === index)) {
// swap with jmp, do jump
// debugger
// console.log('swapped',instruction)
didSwap = true
swapped.push(instruction)
stepIndex += instruction.argument
} else {
stepIndex += 1
// console.log('not swapped',instruction)
}
break;
default:
stepIndex += 1
break;
}
// debugger
setTimeout(() => processStep(stepIndex), 1)
} else {
console.error('invalid instructions at index', index)
}
} else {
//console.warn('looped, trying again', accumulator, swapped.length, swapped.slice(-1)[0])
accumulator = 0
stepIndex = 0
didSwap = false
stepsCompleted = []
// debugger
processStep(stepIndex)
}
}
} else {
console.error('total accumulator:', accumulator, 'index:', index)
}
}
processStep(stepIndex)