DEV Community

Discussion on: Advent of Code 2019 Solution Megathread - Day 5: Sunny with a Chance of Asteroids

Collapse
 
nordfjord profile image
Einar Norðfjörð

JavaScript solution

const { createInterface } = require('readline')

const rl = createInterface({
  input: process.stdin,
  output: process.stdout
})

const question = str =>
  new Promise(res => {
    rl.question(str, res)
  })

const INSTRUCTIONS = {
  ADD: 1,
  MULT: 2,
  INPUT: 3,
  OUTPUT: 4,
  JUMP_IF_TRUE: 5,
  JUMP_IF_FALSE: 6,
  LESS_THAN: 7,
  EQUALS: 8,
  HALT: 99
}

async function runProgram(instructions) {
  instructions = instructions.slice()

  loop: for (let i = 0; i < instructions.length; ++i) {
    const instruction = instructions[i]
    const parsed = String(instruction)
      .padStart(5, '0')
      .split('')
    const valueMode = (value, mode = '0') =>
      mode === '0' ? instructions[value] : value
    const opCode = Number(parsed.slice(3).join(''))
    const modes = parsed.slice(0, 3)
    switch (opCode) {
      case INSTRUCTIONS.ADD: {
        const x = valueMode(instructions[++i], modes[2])
        const y = valueMode(instructions[++i], modes[1])
        instructions[instructions[++i]] = x + y
        break
      }
      case INSTRUCTIONS.MULT: {
        const x = valueMode(instructions[++i], modes[2])
        const y = valueMode(instructions[++i], modes[1])
        instructions[instructions[++i]] = x * y
        break
      }
      case INSTRUCTIONS.INPUT: {
        instructions[instructions[++i]] = Number(await question('input: '))
        break
      }
      case INSTRUCTIONS.OUTPUT: {
        console.log(valueMode(instructions[++i], modes[2]))
        break
      }
      case INSTRUCTIONS.JUMP_IF_TRUE: {
        const compare = valueMode(instructions[++i], modes[2])
        const jumpTo = valueMode(instructions[++i], modes[1]) - 1
        if (compare != 0) {
          i = jumpTo
        }
        break
      }
      case INSTRUCTIONS.JUMP_IF_FALSE: {
        const compare = valueMode(instructions[++i], modes[2])
        const jumpTo = valueMode(instructions[++i], modes[1]) - 1
        if (compare == 0) {
          i = jumpTo
        }
        break
      }
      case INSTRUCTIONS.LESS_THAN: {
        const x = valueMode(instructions[++i], modes[2])
        const y = valueMode(instructions[++i], modes[1])
        instructions[instructions[++i]] = x < y ? 1 : 0
        break
      }
      case INSTRUCTIONS.EQUALS: {
        const x = valueMode(instructions[++i], modes[2])
        const y = valueMode(instructions[++i], modes[1])
        instructions[instructions[++i]] = x === y ? 1 : 0
        break
      }
      case INSTRUCTIONS.HALT:
        break loop
    }
  }
  return instructions[0]
}

module.exports = runProgram

if (process.argv[1] === __filename) {
  const input = require('fs')
    .readFileSync('./puzzle-input.txt')
    .toString()

  const instructions = input.split(',').map(Number)
  runProgram(instructions).then(() => process.exit(0))
}