function silhouette(points, labels) {
    if (points.length !== labels.length) {
        throw new Error("must have exactly as many labels as points");
    }
    const groupings = createGroups(labels);
    const distances = calculateAllDistances(points);
    const result = [];
    for (let i = 0; i < points.length; i++) {
        let s = 0;
        if (groupings[labels[i]].length > 1) {
            const a = meanDistanceFromPointToGroup(
                i,
                groupings[labels[i]],
                distances
            );
            const b = meanDistanceToNearestGroup(
                i,
                labels,
                groupings,
                distances
            );
            s = (b - a) / Math.max(a, b);
        }
        result.push(s);
    }
    return result;
}
Calculate the [silhouette values](https://en.wikipedia.org/wiki/Silhouette_(clustering))
for clustered data.

@param {Array<Array<number>>} points N-dimensional coordinates of points.
@param {Array<number>} labels Labels of points. This must be the same length as `points`,
and values must lie in [0..G-1], where G is the number of groups.
@return {Array<number>} The silhouette value for each point.

@example
silhouette([[0.25], [0.75]], [0, 0]); // => [1.0, 1.0]