Data update
This commit is contained in:
parent
29a5eea0d4
commit
5c1bb7bfa9
2011 changed files with 35081 additions and 3229 deletions
|
|
@ -1,32 +1,44 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
// ------------ LEVENSHTEIN EDIT DISTANCE ------------
|
||||
|
||||
// levenshtein :: String -> String -> Int
|
||||
const levenshtein = sa => sb => {
|
||||
const cs = chars(sa);
|
||||
const go = (ns, c) => {
|
||||
const calc = z => tpl => {
|
||||
const [c1, x, y] = Array.from(tpl);
|
||||
return minimum([
|
||||
succ(y),
|
||||
succ(z),
|
||||
x + (c !== c1 ? 1 : 0)
|
||||
]);
|
||||
const levenshtein = sa =>
|
||||
// The Levenshtein edit distance
|
||||
// between two given strings.
|
||||
sb => {
|
||||
const cs = [...sa];
|
||||
const go = (ns, c) => {
|
||||
const calc = z => tpl => {
|
||||
const [c1, x, y] = Array.from(tpl);
|
||||
|
||||
return Math.min(
|
||||
1 + y,
|
||||
1 + z,
|
||||
x + (
|
||||
c1 === c
|
||||
? 0
|
||||
: 1
|
||||
)
|
||||
);
|
||||
};
|
||||
const [n, ...ns1] = ns;
|
||||
|
||||
return scanl(calc)(1 + n)(
|
||||
zip3(cs)(ns)(ns1)
|
||||
);
|
||||
};
|
||||
const [n, ns1] = [ns[0], ns.slice(1)];
|
||||
return scanl(calc)(succ(n))(
|
||||
zip3(cs)(ns)(ns1)
|
||||
|
||||
return last(
|
||||
[...sb].reduce(
|
||||
go,
|
||||
enumFromTo(0)(cs.length)
|
||||
)
|
||||
);
|
||||
};
|
||||
return last(
|
||||
chars(sb).reduce(
|
||||
go,
|
||||
enumFromTo(0)(cs.length)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
// ----------------------- TEST ------------------------
|
||||
// ---------------------- TEST -----------------------
|
||||
const main = () => [
|
||||
["kitten", "sitting"],
|
||||
["sitting", "kitten"],
|
||||
|
|
@ -35,38 +47,7 @@
|
|||
].map(uncurry(levenshtein));
|
||||
|
||||
|
||||
// ----------------- GENERIC FUNCTIONS -----------------
|
||||
|
||||
// Tuple (,) :: a -> b -> (a, b)
|
||||
const Tuple = a =>
|
||||
b => ({
|
||||
type: 'Tuple',
|
||||
'0': a,
|
||||
'1': b,
|
||||
length: 2
|
||||
});
|
||||
|
||||
|
||||
// TupleN :: a -> b ... -> (a, b ... )
|
||||
function TupleN() {
|
||||
const
|
||||
args = Array.from(arguments),
|
||||
n = args.length;
|
||||
return 2 < n ? Object.assign(
|
||||
args.reduce((a, x, i) => Object.assign(a, {
|
||||
[i]: x
|
||||
}), {
|
||||
type: 'Tuple' + n.toString(),
|
||||
length: n
|
||||
})
|
||||
) : args.reduce((f, x) => f(x), Tuple);
|
||||
};
|
||||
|
||||
|
||||
// chars :: String -> [Char]
|
||||
const chars = s =>
|
||||
s.split('');
|
||||
|
||||
// ---------------- GENERIC FUNCTIONS ----------------
|
||||
|
||||
// enumFromTo :: Int -> Int -> [Int]
|
||||
const enumFromTo = m =>
|
||||
|
|
@ -76,68 +57,53 @@
|
|||
|
||||
|
||||
// last :: [a] -> a
|
||||
const last = xs => (
|
||||
const last = xs => {
|
||||
// The last item of a list.
|
||||
ys => 0 < ys.length ? (
|
||||
ys.slice(-1)[0]
|
||||
) : undefined
|
||||
)(xs);
|
||||
const n = xs.length;
|
||||
|
||||
|
||||
// minimum :: Ord a => [a] -> a
|
||||
const minimum = xs => (
|
||||
// The least value of xs.
|
||||
ys => 0 < ys.length ? (
|
||||
ys.slice(1)
|
||||
.reduce((a, y) => y < a ? y : a, ys[0])
|
||||
) : undefined
|
||||
)(xs);
|
||||
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs =>
|
||||
// Returns Infinity over objects without finite
|
||||
// length. This enables zip and zipWith to choose
|
||||
// the shorter argument when one is non-finite,
|
||||
// like cycle, repeat etc
|
||||
'GeneratorFunction' !== xs.constructor.constructor.name ? (
|
||||
xs.length
|
||||
) : Infinity;
|
||||
return 0 < n
|
||||
? xs[n - 1]
|
||||
: null;
|
||||
};
|
||||
|
||||
|
||||
// scanl :: (b -> a -> b) -> b -> [a] -> [b]
|
||||
const scanl = f => startValue => xs =>
|
||||
xs.reduce((a, x) => {
|
||||
const v = f(a[0])(x);
|
||||
return Tuple(v)(a[1].concat(v));
|
||||
}, Tuple(startValue)([startValue]))[1];
|
||||
const scanl = f =>
|
||||
// The series of interim values arising
|
||||
// from a catamorphism. Parallel to foldl.
|
||||
startValue => xs =>
|
||||
xs.reduce(
|
||||
(a, x) => {
|
||||
const v = f(a[0])(x);
|
||||
|
||||
|
||||
// succ :: Enum a => a -> a
|
||||
const succ = x =>
|
||||
1 + x;
|
||||
return [v, a[1].concat(v)];
|
||||
}, [startValue, [startValue]]
|
||||
)[1];
|
||||
|
||||
|
||||
// uncurry :: (a -> b -> c) -> ((a, b) -> c)
|
||||
const uncurry = f =>
|
||||
// A function over a pair, derived
|
||||
// from a curried function.
|
||||
function () {
|
||||
(...args) => {
|
||||
const
|
||||
args = arguments,
|
||||
xy = Boolean(args.length % 2) ? (
|
||||
args[0]
|
||||
) : args;
|
||||
return f(xy[0])(xy[1]);
|
||||
[x, y] = Boolean(args.length % 2)
|
||||
? args[0]
|
||||
: args;
|
||||
|
||||
return f(x)(y);
|
||||
};
|
||||
|
||||
|
||||
// zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
|
||||
const zip3 = xs =>
|
||||
ys => zs => xs
|
||||
.slice(0, Math.min(...[xs, ys, zs].map(length)))
|
||||
.map((x, i) => TupleN(x, ys[i], zs[i]));
|
||||
ys => zs => xs.slice(
|
||||
0,
|
||||
Math.min(...[xs, ys, zs].map(x => x.length))
|
||||
)
|
||||
.map((x, i) => [x, ys[i], zs[i]]);
|
||||
|
||||
|
||||
// MAIN ---
|
||||
return JSON.stringify(main())
|
||||
return JSON.stringify(main());
|
||||
})();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue