-
-
Save petros/8c6b0effcd78d9e1b3f1c9f4da7299b9 to your computer and use it in GitHub Desktop.
Top Secret - Elixir - Exercism
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule TopSecret do | |
@spec to_ast(String.t()) :: tuple() | |
def to_ast(string), do: Code.string_to_quoted!(string) | |
@spec decode_secret_message_part(tuple(), list()) :: tuple() | |
def decode_secret_message_part(ast, acc) when elem(ast, 0) in [:def, :defp] do | |
ast | |
|> elem(2) | |
|> Enum.at(0) | |
|> get_function_ast() | |
|> get_function_name_and_arity() | |
|> get_sliced_name() | |
|> get_secret_message_part(ast, acc) | |
end | |
def decode_secret_message_part(ast, acc), do: {ast, acc} | |
defp get_secret_message_part(name, ast, acc), do: {ast, [name | acc]} | |
defp get_function_ast(ast) when elem(ast, 0) == :when do | |
ast | |
|> elem(2) | |
|> Enum.at(0) | |
end | |
defp get_function_ast(ast), do: ast | |
defp get_function_name_and_arity(function_ast) do | |
fname = | |
function_ast | |
|> elem(0) | |
|> Atom.to_string() | |
{fname, get_arity(function_ast)} | |
end | |
defp get_arity(function_ast) when elem(function_ast, 2) == nil, do: -1 | |
defp get_arity(function_ast) do | |
function_ast | |
|> elem(2) | |
|> Enum.count() | |
|> Kernel.-(1) | |
end | |
defp get_sliced_name({_fname, arity}) when arity == -1, do: "" | |
defp get_sliced_name({fname, arity}) when arity > -1, do: fname |> String.slice(0..arity) | |
@spec decode_secret_message(String.t()) :: String.t() | |
def decode_secret_message(string) do | |
string | |
|> to_ast() | |
|> Macro.postwalk([], &decode_secret_message_part/2) | |
|> Tuple.to_list() | |
|> Enum.at(1) | |
|> Enum.reverse() | |
|> Enum.join() | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment