const { Glib, BNMath: Math, Vector, twodee: { DIRECTIONS, ORIGIN }, } = require('../../lib'); const midpointDistance = (i) => (Math.sqrt(i - 1n) + 1n) / 2n; const rotationalDistance = (i, md) => { if (i === 1n) { return 0n; } const sideLength = md * 2n; const rotationalOffset = i - ((md * 2n - 1n) ** 2n + 1n); const normalizedRotationalOffset = rotationalOffset % sideLength; const sideOffset = -md + 1n; return Math.abs(normalizedRotationalOffset + sideOffset); }; const distance = (i) => { const md = midpointDistance(i); const rd = rotationalDistance(i, md); // console.log(i, md, rd); return md + rd; }; const order = new Map([ [DIRECTIONS.RIGHT.string, DIRECTIONS.UP], [DIRECTIONS.UP.string, DIRECTIONS.LEFT], [DIRECTIONS.LEFT.string, DIRECTIONS.DOWN], [DIRECTIONS.DOWN.string, DIRECTIONS.RIGHT], ]); const check = new Map([ [DIRECTIONS.RIGHT.string, DIRECTIONS.UP], [DIRECTIONS.UP.string, DIRECTIONS.LEFT], [DIRECTIONS.LEFT.string, DIRECTIONS.DOWN], [DIRECTIONS.DOWN.string, DIRECTIONS.RIGHT], ]); const nextDirection = (current, direction, calculated) => calculated.has(current.add(check.get(direction.string)).string) ? direction : order.get(direction.string); const validate = [ 1n, 1n, 2n, 4n, 5n, 10n, 11n, 23n, 25n, 26n, 54n, 57n, 59n, 122n, 133n, 142n, 147n, 304n, 330n, 351n, 362n, 747n, 806n, 880n, 931n, 957n, 1968n, 2105n, 2275n, 2391n, 2450n, 5022n, 5336n, 5733n, 6155n, 6444n, 6591n, 13486n, 14267n, 15252n, 16295n, 17008n, 17370n, 35487n, 37402n, 39835n, 42452n, 45220n, 47108n, 48065n, 98098n, 103128n, 109476n, 116247n, 123363n, 128204n, 130654n, 266330n, 279138n, 295229n, 312453n, 330785n, 349975n, 363010n, 369601n, 752688n, 787032n, 830037n, 875851n, 924406n, 975079n, 1009457n, 1026827n, 2089141n, 2179400n, 2292124n, 2411813n, 2539320n, 2674100n, 2814493n, 2909666n, 2957731n, 6013560n, 6262851n, ]; module.exports = { '1': (input) => { return distance(BigInt(input)); }, '2': (input) => { const target = BigInt(input); const calculated = new Map([[ORIGIN.string, 1n]]); let direction = DIRECTIONS.UP; let current = DIRECTIONS.RIGHT; let sum = 1n; while (sum < target) { sum = current .neighbors() .map((pt) => pt.string) .lookupInMap(calculated, true) .sum(); calculated.set(current.string, sum); current = current.add(direction); direction = nextDirection(current, direction, calculated); } return sum; a.filter( (char, index) => char === input[(index + input.length / 2) % input.length], ) .toInts() .sum(); }, };