Published
Edited
Dec 14, 2020
Insert cell
Insert cell
solve(input)(parse) // part 1 solution
Insert cell
solve(input)(parse2) // part 2 solution
Insert cell
solve = data => parser => {
const s = data
.split("\n")
// .slice(0,5) // debug
.reduce((acc, inc) => parser(acc)(inc), {wx: 10, wy: -1, x: 0, y: 0}) // apply each instruction to the ship's starting state
// return s // debug
return manhattan(s.x)(s.y)
}
Insert cell
// Given a ship and an instruction, update the ship according to the instruction
// A ship is an object with wx, wy, x, y for waypoint and ship positions
// Ship -> String -> Ship
parse2 = ship => ins => {
let shipclone = clone(ship)
const op = ins.substring(0,1)
const param = +ins.substring(1)
let wheading = Math.atan2(shipclone.wy, shipclone.wx)
let dist = Math.sqrt(Math.pow(shipclone.wx,2) + Math.pow(shipclone.wy,2))
switch(op) {
case "N":
shipclone.wy-=param
break;
case "S":
shipclone.wy+=param
break;
case "E":
shipclone.wx+=param
break;
case "W":
shipclone.wx-=param
break;
case "F":
shipclone.x += Math.cos(wheading) * param * dist
shipclone.y += Math.sin(wheading) * param * dist
break;
case "L":
wheading-=radians(param)
shipclone.wx = Math.cos(wheading) * dist
shipclone.wy = Math.sin(wheading) * dist
break;
case "R":
wheading+=radians(param)
shipclone.wx = Math.cos(wheading) * dist
shipclone.wy = Math.sin(wheading) * dist
break;
}
return shipclone
}
Insert cell
// Given a ship and an instruction, update the ship according to the instruction
// A ship is an object with wx, wy, x, y for waypoint and ship positions
// Ship -> String -> Ship
parse = ship => ins => {
let shipclone = clone(ship)
const op = ins.substring(0,1)
const param = +ins.substring(1)
switch(op) {
case "N":
shipclone.y-=param
break;
case "S":
shipclone.y+=param
break;
case "E":
shipclone.x+=param
break;
case "W":
shipclone.x-=param
break;
case "F":
shipclone.x += Math.cos(radians(shipclone.heading)) * param
shipclone.y += Math.sin(radians(shipclone.heading)) * param
break;
case "L":
shipclone.heading += -param
break;
case "R":
shipclone.heading += param
break;
}
return shipclone
}
Insert cell
radians = x => x * Math.PI/180
Insert cell
manhattan = x => y => Math.abs(x) + Math.abs(y)
Insert cell
clone = x => JSON.parse(JSON.stringify(x))
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more