simponic.xyz/euler-golf/js/sol.js

42 lines
1.3 KiB
JavaScript
Raw Normal View History

2023-02-23 20:18:31 -05:00
const DEPTH = 21;
2023-02-23 12:15:07 -05:00
const DIRECTION = {
0: new cx(0, 1),
1: new cx(0, -1),
};
const move = (prev, curr, c) => cx.add(prev, cx.mult(c, cx.sub(curr, prev)));
2023-02-23 20:18:31 -05:00
2023-02-23 12:15:07 -05:00
const construct_moves = (curr, prev) =>
Object.keys(DIRECTION).map((x) => move(curr, prev, DIRECTION[x]));
2023-02-23 20:18:31 -05:00
2023-02-23 12:15:07 -05:00
const backtrack = (local_index, depth) =>
local_index
.toString(2)
.padStart(depth, "0")
.split("")
2023-02-23 20:18:31 -05:00
.map((direction) => (Number(direction) ? "-" : "+"));
2023-02-23 12:15:07 -05:00
const sol = (target, start_from = new cx(0, 0), start_to = new cx(1, 0)) => {
2023-02-23 20:18:31 -05:00
let moves = [start_to, ...construct_moves(start_from, start_to)];
let curr_depth = 2;
2023-02-23 12:15:07 -05:00
2023-02-23 20:18:31 -05:00
while (curr_depth < DEPTH) {
2023-02-23 12:15:07 -05:00
for (let i = 0; i < Math.pow(2, curr_depth); i++) {
2023-02-23 20:18:31 -05:00
const direction = DIRECTION[Number(i.toString(2).at(-1))];
// Current element is at i >> 1 + the offset for the previous group (which is
// the sum of the geometric series 2**n until curr_depth - 1)
const current_i = (i >> 1) + (1 - Math.pow(2, curr_depth - 1)) / (1 - 2);
const previous_i = (i >> 2) + (1 - Math.pow(2, curr_depth - 2)) / (1 - 2);
2023-02-23 12:15:07 -05:00
2023-02-23 20:18:31 -05:00
const new_move = move(moves[previous_i], moves[current_i], direction);
2023-02-23 12:15:07 -05:00
moves.push(new_move);
2023-02-23 20:18:31 -05:00
if (cx.eq(new_move, target)) return backtrack(i, curr_depth);
2023-02-23 12:15:07 -05:00
}
curr_depth++;
2023-02-23 20:18:31 -05:00
}
2023-02-23 12:15:07 -05:00
return null;
};