diff --git a/plugins/FunCommands.py b/plugins/FunCommands.py index 9fe38185a..975ec04cc 100644 --- a/plugins/FunCommands.py +++ b/plugins/FunCommands.py @@ -56,6 +56,7 @@ Commands include: last lastfrom lithp + levenshtein pydoc """ @@ -423,6 +424,15 @@ class FunCommands(callbacks.Privmsg): return irc.error(msg, 'I don\'t remember a message from that person.') + def levenshtein(self, irc, msg, args): + """ + + Returns the levenshtein distance (also known as the "edit distance" + between and + """ + (s1, s2) = privmsgs.getArgs(args, needed=2) + irc.reply(msg, str(utils.distance(s1, s2))) + modulechars = '%s%s%s' % (string.ascii_letters, string.digits, '_.') def pydoc(self, irc, msg, args): """ diff --git a/src/utils.py b/src/utils.py index 4a2236013..06a4a1e6c 100755 --- a/src/utils.py +++ b/src/utils.py @@ -152,6 +152,26 @@ def timeElapsed(now, then, leadingZeroes=False, years=True, weeks=True, else: return ' and '.join([', '.join(ret[:-1]), ret[-1]]) +def distance(s, t): + n = len(s) + m = len(t) + if n == 0: + return m + elif m == 0: + return n + d = range(n+1) + for i in range(len(d)): + d[i] = range(m+1) + for i in range(1, n+1): + cs = s[i-1] + for j in range(1, m+1): + ct = t[j-1] + if cs == ct: + cost = 0 + else: + cost = 1 + d[i][j] = min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+cost) + return d[n][m] # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: diff --git a/test/utils_test.py b/test/utils_test.py index c4fc74b2c..09437569e 100644 --- a/test/utils_test.py +++ b/test/utils_test.py @@ -53,3 +53,12 @@ class UtilsTest(unittest.TestCase): s = 'foobar' L = ['f', 'fo', 'foo', 'foob', 'fooba', 'foobar'] self.assertEqual(list(utils.eachSubstring(s)), L) + + def testDistance(self): + self.assertEqual(utils.distance('', ''), 0) + self.assertEqual(utils.distance('a', 'b'), 1) + self.assertEqual(utils.distance('a', 'a'), 0) + self.assertEqual(utils.distance('foobar', 'jemfinch'), 8) + self.assertEqual(utils.distance('a', 'ab'), 1) + self.assertEqual(utils.distance('foo', ''), 3) + self.assertEqual(utils.distance('', 'foo'), 3)