|
const I = [2, 4, 2, 3, 6, 5, 4, 4, 8, 2, 4, 1, 3, 6, 4, 3, 4, 4, 3] |
|
const M = [2, 3, 3, 4, 2, 3, 3, 4, 2, 3, 5, 3, 3, 2, 4, 5, 3, 3, 1, 2, 1] |
|
const F = [0, 2, 4, 4, 2, 5, 5, 3, 5, 7, 9, 9, 7, 9, 9, 8, 4, 5, 7, 2, 4, 1, 3, 4, 3, 4, 4, 3] |
|
|
|
const getLineCount = (char: string) => { |
|
const code = char.charCodeAt(0) - 0xac00 |
|
return code < 0 || code > 11172 ? 0 : I[Math.floor(code / (M.length * F.length))] + M[Math.floor((code % (M.length * F.length)) / F.length)] + F[code % F.length] |
|
} |
|
|
|
export default function* match(a: string, b: string) { |
|
const length = Math.max(a.length, b.length) |
|
const [x, y] = [[...a.padEnd(length, '*')], [...b.padEnd(length, '*')]] |
|
|
|
const zip = Array.from({ length }).flatMap((_, i) => [x[i], y[i]]) |
|
yield zip |
|
|
|
let value = zip.map(getLineCount) |
|
yield value |
|
|
|
while (value.length > 2) yield (value = Array.from({ length: value.length - 1 }, (_, i) => (value[i] + value[i + 1]) % 10)) |
|
yield value[0] * 10 + value[1] |
|
} |