Skip to content

Instantly share code, notes, and snippets.

@yrashk
Forked from plukevdh/leven.ex
Created November 28, 2012 20:44
Show Gist options
  • Save yrashk/4164305 to your computer and use it in GitHub Desktop.
Save yrashk/4164305 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, :dict.new)
list
end
def distance(string_1, []=string_2, cache) do
length = :string.len string_1
{length, :dict.store({string_1,string_2}, length, cache)}
end
def distance([]=string_1, string_2, cache) do
length = :string.len string_2
{length, :dict.store({string_1,string_2}, length, cache)}
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.is_key({string_1, string_2}, cache) do
true -> {:dict.fetch({string_1, string_2}, cache), cache}
false ->
{l1, c1} = distance(string_1, rest2, cache)
{l2, c2} = distance(rest1, string_2, c1)
{l3, c3} = distance(rest1, rest2, c2)
min = :lists.min([l1, l2, l3]) + 1
{min, :dict.store({string_1,string_2}, min, c3)}
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