/**
 * Levenshtein distance between two strings.
 * Used to find similar command names, if user
 * misspelled the command name.
 *
 * @example
 * distance('actvate', 'activate'); // returns 1
 * distance('lits', 'list'); // returns 2
 *
 * @see https://en.wikipedia.org/wiki/Levenshtein_distance
 *
 * @param {string} str0 - first string
 * @param {string} str1 - second string
 * @returns {number} distance between strings
 */
export const distance = (str0, str1) => {
    const s0len = str0.length;
    const s1len = str1.length;
    const column = Array(s0len+1);

    for (let y = 1; y <= s0len; y++) {
        column[y] = y;
    }
    for (let x = 1; x <= s1len; x++) {
        column[0] = x;
        let lastkey = x - 1;
        for (let y = 1; y <= s0len; y++) {
            const oldkey = column[y];
            const incr = str0[y - 1] !== str1[x - 1] ? 1 : 0;
            column[y] = Math.min(column[y] + 1, column[y - 1] + 1, lastkey + incr);
            lastkey = oldkey;
        }
    }
    return column[s0len];
};
