Site icon R-bloggers

Advent of Code 2019-05 with R & JavaScript

[This article was first published on Colin Fay, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Solving Advent of Code 2019-05 with R and JavaScript.

[Disclaimer] Obviously, this post contains a big spoiler about Advent of Code, as it gives solutions for solving day 5.

[Disclaimer bis] I’m no JavaScript expert so this might not be the perfect solution. TBH, that’s also the case for the R solution.

About the JavaScript code

The JavaScript code has been written in the same RMarkdown as the R code. It runs thanks to the {bubble} package: https://github.com/ColinFay/bubble

Instructions

Find the instructions at: https://adventofcode.com/2019/day/5

R solution

vec <- scan("input5.txt", numeric(), sep = ",")
library(magrittr)
library(zeallot)
parse_opcode <- function(vec, pos){
  code <- vec[pos]
  op_code <- stringr::str_pad(
    as.character(code), 
    5, 
    side = "left", "0"
  ) %>% strsplit(split = "")
  op_code <- op_code[[1]] %>% 
    setNames(letters[1:5])
  list(
    op_code = paste0(
      op_code[4:5], 
      collapse = ""
    ) %>% as.numeric(), 
    c = op_code["c"],
    b = op_code["b"], 
    a = op_code["a"]
  ) %>%
    one_two_three(
      vec, 
      pos
    )
}

one_two_three <- function(res, vec, pos){
  if (res$c == "0"){
    one <- vec[vec[pos + 1] + 1]
  } else {
    one <- vec[pos + 1] 
  } 
  if (res$b == "0"){
    two <- vec[vec[pos + 2] + 1]
  } else {
    two <- vec[pos + 2] 
  } 
  if (res$a == "0"){
    three <- vec[pos + 3] + 1
  } else {
    three <- vec[pos + 3]
  } 
  list(
    res$op_code,
    one, 
    two, 
    three
  )
}

prog <- function(vec, ipt){
  pos <- 1
  while (pos < length(vec)) {
    
    c(op_code, one, two, three) %<-%  parse_opcode( vec,  pos )
    
    if (op_code == 99) break
    
    if (op_code %in% 1:2){
      
      if (op_code == 1) fun <- `+`
      if (op_code == 2) fun <- `*`
      vec[three] <- fun(one, two)
      pos <- pos + 4
    } else if (op_code == 3){
      vec[ vec[pos + 1] + 1 ] <- ipt
      pos <- pos + 2
    } else if (op_code == 4){
      print(vec[vec[pos + 1] + 1])
      pos <- pos + 2
    } else if (op_code == 5){
      if (one != 0){
        pos <- two + 1
      } else {
        pos <- pos + 3
      }
    } else if (op_code == 6){
      if (one == 0){
        pos <- two + 1
      } else {
        pos <- pos + 3
      }
    } else if (op_code == 7){
      if (one < two){
        vec[three] <- 1 
      } else {
        vec[three] <- 0 
      }
      pos <- pos + 4
    } else if (op_code == 8){
      if (one == two){
        vec[three] <- 1 
      } else {
        vec[three] <- 0 
      }
      pos <- pos + 4
    }
  }
}
prog(vec, 1)

## [1] 3
## [1] 0
## [1] 0
## [1] 0
## [1] 0
## [1] 0
## [1] 0
## [1] 0
## [1] 0
## [1] 6731945

Part two

prog(vec, 5)

## [1] 9571668

JS solution

Part one & Two

var vec = fs.readFileSync("input5.txt", 'utf8').split(",").map(x => parseInt(x)).filter(x => x.length != 0)

function parse_opcode(vec, pos){
  var code = vec[pos];
  code = code.toString();
  while(code.length < 5){
    code = '0' + code
  }
  code = code.split("");
  var l = [];
  l.opcode = code[3] + code[4]
  l.c = code[2]
  l.b = code[1]
  l.a = code[0]
  var res = one_two_three(l, vec, pos);
  return res
}

function one_two_three(l, vec, pos){
  var out = {};
  out.opcode = l.opcode;
  if (l.c == "0"){
    out.one = vec[vec[pos + 1]]
  } else {
    out.one = vec[pos + 1] 
  } 
  if (l.b === "0"){
    out.two = vec[vec[pos + 2]]
  } else {
    out.two = vec[pos + 2] 
  } 
  if (l.a === "0"){
    out.three = vec[pos + 3]
  } else {
    three = vec[pos + 3]
  } 
  return out
}

function prog(vec, ipt){
  var vec = vec.slice()
  var pos = 0;
  res = [];
  while (pos < vec.length) {
    var out = parse_opcode( vec,  pos );
    var op_code = parseInt(out.opcode);
    var one =  parseInt(out.one);
    var two = parseInt(out.two);
    var three = parseInt(out.three);
    
    if (op_code == 99) break
    
    if (op_code == 1) {
      vec[three] = one + two;
      pos = pos + 4;
    } else  if (op_code == 2) {
      vec[three] = one * two;
      pos = pos + 4;
    } else if (op_code == 3){
      vec[ vec[pos + 1] ] = ipt
      pos = pos + 2
    } else if (op_code == 4){
      res.push(vec[vec[pos + 1]])
      pos = pos + 2
    } else if (op_code === 5){
      if (one !== 0){
        pos = two 
      } else {
        pos = pos + 3
      }
    } else if (op_code === 6){
      if (one === 0){
        pos = two 
      } else {
        pos = pos + 3
      }
    } else if (op_code === 7){
      if (one < two){
        vec[three] = 1 
      } else {
        vec[three] = 0 
      }
      pos = pos + 4
    } else if (op_code === 8){
      if (one == two){
        vec[three] = 1 
      } else {
        vec[three] = 0 
      }
      pos = pos + 4
    }
  }
  return res.pop()
}

prog(vec, 1)

## 6731945

prog(vec, 5)

## 9571668

To leave a comment for the author, please follow the link and comment on their blog: Colin Fay.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.