Skip to content

Instantly share code, notes, and snippets.

@yrashk
Forked from plukevdh/leven.ex
Created November 28, 2012 20:58
Show Gist options
  • Save yrashk/4164441 to your computer and use it in GitHub Desktop.
Save yrashk/4164441 to your computer and use it in GitHub Desktop.
Levenshtein in elixir
defmodule Levenshtein do
def first_letter_check(one_letter, two_letter) do
case one_letter == two_letter do
true -> 0
false -> 1
end
end
def distance(string_1, string_1), do: 0
def distance(string, ''), do: :string.len(string)
def distance('', string), do: :string.len(string)
def distance([h1|rest1], [h2|rest2]) do
cost = first_letter_check(h1, h2)
:lists.min([
distance(rest1, [h2|rest2]) + 1,
distance([h1|rest1], rest2) + 1,
distance(rest1, rest2) + cost
])
end
end
IO.inspect :timer.tc(Levenshtein, :distance, ['kitten', 'sitting'])
IO.inspect :timer.tc(Levenshtein, :distance, ['space balls', 'base spalls'])
defmodule Levenshtein do
def distance(string_1, string_2) do
{list, _} = distance(string_1, string_2, OrdDict.new)
list
end
def distance(string_1, []=string_2, cache) do
length = length string_1
{length, Dict.put(cache, {string_1,string_2}, length)}
end
def distance([]=string_1, string_2, cache) do
length = length string_2
{length, Dict.put(cache, {string_1,string_2}, length)}
end
def distance([x|rest1], [x|rest2], cache) do
distance(rest1, rest2, cache)
end
def distance([_|rest1]=string_1, [_|rest2]=string_2, cache) do
case Dict.has_key?(cache, {string_1, string_2}) do
true -> {Dict.get(cache, {string_1, string_2}), cache}
false ->
{l1, c1} = distance(string_1, rest2, cache)
{l2, c2} = distance(rest1, string_2, cache)
{l3, c3} = distance(rest1, rest2, cache)
min = :lists.min([l1, l2, l3]) + 1
{min, Dict.put(c3, {String1,String2}, min)}
end
end
end
IO.inspect :timer.tc(Levenshtein, :distance, ['kitten', 'sitting'])
IO.inspect :timer.tc(Levenshtein, :distance, ['space balls', 'base spalls'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment