lib/caesar_cipher.ex

defmodule CaesarCipher do
  @moduledoc """
  Documentation for `CaesarCipher`.
  """

  @caesar_map_upper ~w/A B C D E F G H I J K L M N O P Q R S T U V W X Y Z/
  @caesar_map_lower ~w/a b c d e f g h i j k l m n o p q r s t u v w x y z/
  @alphabet_lenght 26

    @doc """
    This function encrypt a string with the salt specified.

    ## Examples Encrypt
      iex> CaesarCipher.encrypt("Hello World!", 2) 
      "Jgnnq Yqtnf!"

  """
  def encrypt(word, salt) do
    run(String.split(word, ""), salt, :+, [])
  end

  @doc """
    This function decrypt a string with the salt specified.

    ## Examples Decrypt
      iex> CaesarCipher.decrypt("Jgnnq Yqtnf!", 2) 
      "Hello World!"
  """
  def decrypt(word, salt) do
    run(String.split(word, ""), salt, :-, [])
  end

  defp convertToString([""], _, _, result) do
    List.to_string(result)
  end

  defp run([h | t], salt, operator, result) do

    caesar_map = if Unicode.uppercase?(h), do:  @caesar_map_upper, else: @caesar_map_lower

    index = Enum.find_index(caesar_map, fn n -> n == h end)

    replacement =
      if index do
        adjustment = apply(Kernel, operator, [index, salt])
        Enum.at(caesar_map, rem(adjustment, @alphabet_lenght))
      else
        h
      end

      if t ==  [""] do
        convertToString(t, salt, operator, result ++ [replacement])
      else
        run(t, salt, operator, result ++ [replacement])
      end
  end
end