domain/converters/learning.route.converter.ts

domain/converters/learning.route.converter.ts is a file in Bane's Lab Site. 35 lines of code and 11 definitions.

import type { LearningPoint } from "#types/learning.types";

interface RailStop {
    readonly cx: number;
    readonly cy: number;
}

const turnsBack = function turnsBack(before: LearningPoint, here: LearningPoint, after: LearningPoint): boolean {
    const upright = before.x === here.x && here.x === after.x;
    const level = before.y === here.y && here.y === after.y;
    const along = (here.x - before.x) * (after.x - here.x) + (here.y - before.y) * (after.y - here.y);
    return (upright || level) && along < 0;
};

const isSpur = function isSpur(rail: readonly LearningPoint[], index: number, stops: readonly RailStop[]): boolean {
    const [before, here, after] = rail.slice(index - 1, index + 2);
    if (before === undefined || here === undefined || after === undefined) {
        return false;
    }
    const atStop = stops.some((stop) => stop.cx === here.x && stop.cy === here.y);
    return !atStop && turnsBack(before, here, after);
};

export const unfold = function unfold(
    rail: readonly LearningPoint[],
    stops: readonly RailStop[],
): readonly LearningPoint[] {
    const held = [...rail];
    let index = 1;
    while (index < held.length - 1) {
        if (isSpur(held, index, stops)) {
            held.splice(index, 1);
            index = Math.max(1, index - 1);
        } else {
            index += 1;
        }
    }
    return held;
};