const Glib = require('./Glib'); const Vector = require('./Vector'); const ORIGIN = new Vector(0, 0); const DIRECTIONS = { UP: new Vector(0, 1), DOWN: new Vector(0, -1), LEFT: new Vector(-1, 0), RIGHT: new Vector(1, 0), }; class Rectangle { static fromPoints(one, two) { const [x1, x2] = [one.v[0], two.v[0]].sortInts(); const [y1, y2] = [one.v[1], two.v[1]].sortInts(); const bottomLeft = new Vector(x1, y1); const size = bottomLeft .multiply(-1) .add(new Vector(x2, y2)) .add(1n); return new Rectangle(bottomLeft, size); } static fromXXYY(x1, x2, y1, y2) { return Rectangle.fromPoints(new Vector(x1, y1), new Vector(x2, y2)); } constructor(offset, size) { // console.log(`${offset.string} ${offset.add(size).string}`); // todo: normalize? this.offset = offset; this.size = size; } allPoints() { return new Glib( (function*(_this) { const [startX, startY] = _this.offset.toArray(); const [endX, endY] = _this.offset.add(_this.size).toArray(); for (let x = startX; x < endX; x++) { for (let y = startY; y < endY; y++) { yield new Vector(x, y); } } })(this), ); } get bottomLeft() { return this.offset; } get topRight() { return this.offset.add(this.size); } } class Instruction { static fromString(string, instructionSet) { const [char, ...num] = string.split(''); if (!instructionSet.hasOwnProperty(char)) { throw new Error('invalid move'); } const move = instructionSet[char]; return num.length === 0 ? new Instruction(move) : new Instruction(move, BigInt(num.join(''))); } constructor(move, count = 1n) { this.move = move; this.count = count; } jump(source) { // console.log(this.count); return source.add(this.move.multiply(this.count)); } walk(source) { return new Glib( (function*(_this) { for (let i = 0n; i < _this.count; i++) { // console.log(source.string); source = source.add(_this.move); yield source; } // console.log(source.string); })(this), ); } } module.exports = { Instruction, Rectangle, DIRECTIONS, ORIGIN, '^v<>': { '^': DIRECTIONS.UP, v: DIRECTIONS.DOWN, '<': DIRECTIONS.LEFT, '>': DIRECTIONS.RIGHT, }, udlr: { u: DIRECTIONS.UP, d: DIRECTIONS.DOWN, l: DIRECTIONS.LEFT, r: DIRECTIONS.RIGHT, }, UDLR: { U: DIRECTIONS.UP, D: DIRECTIONS.DOWN, L: DIRECTIONS.LEFT, R: DIRECTIONS.RIGHT, }, everyStep(instructions, source = ORIGIN) { return new Glib( (function*() { for (const instruction of instructions) { // console.log(instruction); yield* instruction.walk(source); source = instruction.jump(source); } })(), ); }, };