Advent of Code 2019-05 with R & JavaScript
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
What do you think?