RosettaCodeData/Task/Soundex/Elixir/soundex.ex

40 lines
1.2 KiB
Elixir

defmodule Soundex do
def soundex([]), do: []
def soundex(str) do
[head|tail] = String.upcase(str) |> to_char_list
[head | isoundex(tail, [], todigit(head))]
end
defp isoundex([], acc, _) do
case length(acc) do
n when n == 3 -> Enum.reverse(acc)
n when n < 3 -> isoundex([], [?0 | acc], :ignore)
n when n > 3 -> isoundex([], Enum.slice(acc, n-3, n), :ignore)
end
end
defp isoundex([head|tail], acc, lastn) do
dig = todigit(head)
if dig != ?0 and dig != lastn do
isoundex(tail, [dig | acc], dig)
else
case head do
?H -> isoundex(tail, acc, lastn)
?W -> isoundex(tail, acc, lastn)
n when n in ?A..?Z -> isoundex(tail, acc, dig)
_ -> isoundex(tail, acc, lastn) # This clause handles non alpha characters
end
end
end
@digits '01230120022455012623010202'
defp todigit(chr) do
if chr in ?A..?Z, do: Enum.at(@digits, chr - ?A),
else: ?0 # Treat non alpha characters as a vowel
end
end
IO.puts Soundex.soundex("Soundex")
IO.puts Soundex.soundex("Example")
IO.puts Soundex.soundex("Sownteks")
IO.puts Soundex.soundex("Ekzampul")