jsadvent/solutions/2017/3.js

163 lines
2.8 KiB
JavaScript
Raw Permalink Normal View History

2020-12-10 08:33:00 +00:00
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();
},
};