diff --git a/solutions/elixir/rotational-cipher/1/lib/rotational_cipher.ex b/solutions/elixir/rotational-cipher/1/lib/rotational_cipher.ex new file mode 100644 index 0000000..001b746 --- /dev/null +++ b/solutions/elixir/rotational-cipher/1/lib/rotational_cipher.ex @@ -0,0 +1,26 @@ +defmodule RotationalCipher do + @doc """ + Given a plaintext and amount to shift by, return a rotated string. + + Example: + iex> RotationalCipher.rotate("Attack at dawn", 13) + "Nggnpx ng qnja" + """ + @spec rotate(text :: String.t(), shift :: integer) :: String.t() + def rotate(text, shift), do: text |> String.to_charlist() |> shift_letters(shift) + + defp shift_letters(charlist, shift, encoded_text \\ "") + defp shift_letters([], _, encoded_text), do: encoded_text + defp shift_letters([char | tail], shift, encoded_text) when char in ?A..?Z do + encoded_char = if (char + shift) > ?Z, do: char - 26 + shift, else: char + shift + shift_letters(tail, shift, encoded_text <> <>) + end + + defp shift_letters([char | tail], shift, encoded_text) when char in ?a..?z do + encoded_char = if (char + shift) > ?z, do: char - 26 + shift, else: char + shift + shift_letters(tail, shift, encoded_text <> <>) + end + + defp shift_letters([char | tail], shift, encoded_text), + do: shift_letters(tail, shift, encoded_text <> <>) +end