exercism/elixir/atbash-cipher/lib/atbash.ex

49 lines
1.1 KiB
Elixir

defmodule Atbash do
@letters ?a..?z
|> Enum.to_list
|> to_string
|> String.graphemes()
@digits ?0..?9
|> Enum.to_list
|> to_string
|> String.graphemes()
@table Map.new(Enum.zip(@letters, Enum.reverse(@letters)))
defguardp is_letter(char) when char in @letters
defguardp is_digit(char) when char in @digits
@doc """
Encode a given plaintext to the corresponding ciphertext
## Examples
iex> Atbash.encode("completely insecure")
"xlnko vgvob rmhvx fiv"
"""
@spec encode(String.t()) :: String.t()
def encode(plaintext) do
plaintext
|> transpose()
|> String.graphemes()
|> Enum.chunk_every(5)
|> Enum.join(" ")
end
@spec decode(String.t()) :: String.t()
def decode(cipher), do: transpose(cipher)
defp transpose(string) do
string
|> String.downcase()
|> String.graphemes()
|> Enum.map(&code/1)
|> Enum.join()
end
defp code(char) when is_digit(char), do: char
defp code(char) when is_letter(char), do: @table[char]
defp code(_char), do: nil
end