Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Phone mnemonics in Erlang
-module(mnemonics).
-export([translate/1]).
-define(MNEMONICS, [{2, "ABC"}, {3, "DEF"}, {4, "GHI"}, {5, "JKL"}, {6, "MNO"}, {7, "PQRS"}, {8, "TUV"}, {9, "WXYZ"}]).
-define(WORDS, []).
% Public API
translate(StringNumber) ->
Result2 = encode(StringNumber, fun(X) -> sets:to_list(sets:from_list(slab(X))) end),
Result = sets:from_list(Result2),
Strings = sets:fold(fun(Words, AccIn) -> [string:join(filter_empty(Words), " ")|AccIn] end, [], Result),
filter_empty(Strings).
% Private API
wordCode(Word, CharCode) ->
lists:map(fun(Char) -> dict:fetch(Char, CharCode) end, string:to_upper(Word)).
wordsForNum(StringNumber) ->
CharCodeNested = lists:map(fun({N, Str}) -> lists:map(fun(Char) -> {Char, N} end, Str) end, ?MNEMONICS),
CharCode = dict:from_list(lists:flatten(CharCodeNested)),
NumWords = lists:map(fun(Word) -> {Word, wordCode(Word, CharCode)} end, ?WORDS),
WordsDict = lists:foldl(fun({Word, Code}, AccIn) ->
CodeString = string:join(lists:map(fun(Char) -> integer_to_list(Char) end, Code), ""),
dict:append(CodeString, Word, AccIn) end, dict:new(), NumWords),
case dict:is_key(StringNumber, WordsDict) of
true ->
dict:fetch(StringNumber, WordsDict);
false ->
[]
end.
encode(StringNumber, Fun) ->
L = length(StringNumber),
Res = lists:map(fun(Idx) -> Word = wordsForNum(string:substr(StringNumber, 1, Idx)),
Rest = encode(string:substr(StringNumber, Idx + 1, L), fun(X) -> X end),
Fun([Word|Rest]) end, lists:seq(1, L)),
Res.
filter_empty(List) ->
filter_empty(List, []).
filter_empty([], AccIn) -> AccIn;
filter_empty([H|T], AccIn) when is_list(H) andalso length(H) == 0 ->
filter_empty(T, AccIn);
filter_empty([H|T], AccIn) ->
filter_empty(T, [H|AccIn]).
slab([]) ->
[];
slab([F|R]) ->
case io_lib:char_list(F) of
true -> [F|slab(R)];
false -> slab(F) ++ slab(R)
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.