scoring abbreviation

Alcor の Abbreviation Scoring
goruby 的省略形に順位を付ける話。
IRC で話題に上った LiquidMetal を見てもっと簡単にできそうと考え古い方のパーサに入れてみた*1のが一月半前。個人的に重宝している。実装はコレ↓

// Represents how well an abbreviation matches the original
// as a float number 1 (perfect) to 0 (invalid).
// Inspired by <http://github.com/rmm5t/liquidmetal/tree/master>.
function hagureMetal(abbr, orig) {
  var len = orig.length;
  if (len < abbr.length) return 0;
  var sum = 0, score = 1, preIndex = -1, {pow} = Math;
  for each (let c in abbr) {
    let index = orig.indexOf(c, preIndex + 1);
    if (index < 0) return 0;
    if (index !== preIndex + 1) score = pow((len - index) / len, 3);
    sum += (/[\s_-]/.test(orig[index - 1])
            ? pow(score, .3) // beginning of a word
            : score);
    preIndex = index;
  }
  return sum / len;
}
function say(){ dump(Array.join(arguments, '') +'\n') }
for each(a in ['google', 'googl', 'ggl', 'gge', 'ole', 'e', 'G'])
  say(a, '\t', hagureMetal(a, 'google'));
say();
for each(a in ['v ao', 'va-o', 'add', 'edd', 'ddo', 'dd-n'])
  say(a, '\t', hagureMetal(a, 'view add-on'));
google	1
googl	0.8333333333333334
ggl	0.20833333333333334
gge	0.18827160493827158
ole	0.1087962962962963
e	0.0007716049382716048
G	0

v ao	0.19446359513239428
va-o	0.17367198593637584
add	0.08219154995842314
edd	0.06686701728024043
ddo	0.0366764566920243
dd-n	0.02568130592172665

三乗する*2辺りがいかにも怪しい。

*

単語先頭ボーナスの付け方が適当過ぎる((二番目の例で 'add' がトップに来ていた))ことに気付いてしまい修正。
怪しい処理が増えた。

*1:Parser 2 がデフォルトになったのをいいことにやりたい放題である

*2:Parser 1 の元の挙動に近付けようと弄るうちにこうなった