jsadvent/solutions/2016/1.js

88 lines
2.1 KiB
JavaScript
Raw Normal View History

2020-12-10 08:33:00 +00:00
const { Glib, Vector } = require('../../lib');
const DIRECTIONS = {
NORTH: 'NORTH',
SOUTH: 'SOUTH',
EAST: 'EAST',
WEST: 'WEST',
};
const TURNS = {
LEFT: 'L',
RIGHT: 'R',
};
const TURN = {
[TURNS.LEFT]: {
[DIRECTIONS.NORTH]: DIRECTIONS.WEST,
[DIRECTIONS.EAST]: DIRECTIONS.NORTH,
[DIRECTIONS.SOUTH]: DIRECTIONS.EAST,
[DIRECTIONS.WEST]: DIRECTIONS.SOUTH,
},
[TURNS.RIGHT]: {
[DIRECTIONS.NORTH]: DIRECTIONS.EAST,
[DIRECTIONS.EAST]: DIRECTIONS.SOUTH,
[DIRECTIONS.SOUTH]: DIRECTIONS.WEST,
[DIRECTIONS.WEST]: DIRECTIONS.NORTH,
},
};
const MOVE = {
[DIRECTIONS.NORTH]: new Vector(0, 1),
[DIRECTIONS.EAST]: new Vector(1, 0),
[DIRECTIONS.SOUTH]: new Vector(0, -1),
[DIRECTIONS.WEST]: new Vector(-1, 0),
};
const START = new Vector(0, 0);
const parse = (input) =>
Glib.fromIterable(input.trim().split(',')).map((i) => {
const [turn, ...distance] = i.trim();
if (turn !== TURNS.LEFT && turn !== TURNS.RIGHT) {
throw new Error('Invalid turn');
}
return {
turn,
distance: parseInt(distance.join(''), 10),
};
});
module.exports = {
'1': (input) => {
input = parse(input);
let direction = DIRECTIONS.NORTH;
let location = START;
for (const { turn, distance } of input) {
direction = TURN[turn][direction];
const moveVector = MOVE[direction].multiply(distance);
location = location.add(moveVector);
}
return START.distance(location);
},
'2': (input) => {
input = parse(input);
let direction = DIRECTIONS.NORTH;
let location = START;
let visited = new Set();
for (const { turn, distance } of input) {
direction = TURN[turn][direction];
const destination = location.add(MOVE[direction].multiply(distance))
.string;
let locStr = location.string;
while (locStr != destination) {
if (visited.has(locStr)) {
return START.distance(location);
}
visited.add(locStr);
location = location.add(MOVE[direction]);
locStr = location.string;
}
}
},
parse,
};