Sha256: 672cf0e9c68650c00ff31817474ec4a19aaf85b05c40e649223b66394a461e28

Contents?: true

Size: 1.54 KB

Versions: 69

Compression:

Stored size: 1.54 KB

Contents

defmodule RailFenceCipher do
  @doc """
  Encode a given plaintext to the corresponding rail fence ciphertext
  """
  @spec encode(String.t(), pos_integer) :: String.t()
  def encode(str, 1), do: str

  def encode(str, rails) do
    str
    |> String.codepoints()
    |> fill_fence(rails)
    |> Enum.join()
  end

  @doc """
  Decode a given rail fence ciphertext to the corresponding plaintext
  """
  @spec decode(String.t(), pos_integer) :: String.t()
  def decode(str, 1), do: str

  def decode(str, rails) do
    0..(String.length(str) - 1)
    |> Enum.to_list()
    |> fill_fence(rails)
    |> extract_original(str)
  end

  defp extract_original(fence, str) do
    0..(String.length(str) - 1)
    |> Enum.map(fn i ->
      String.at(str, Enum.find_index(fence, &(&1 == i)))
    end)
    |> Enum.join()
  end

  defp fill_fence(list_chars, rails) do
    rail_zigzag_indexes = Enum.concat(Enum.to_list(0..(rails - 1)), Enum.to_list((rails - 2)..1))

    create_empty_fence(rails, length(list_chars))
    |> set_chars_to_fence(list_chars, rail_zigzag_indexes)
  end

  defp create_empty_fence(rows, cols) do
    0..(rows - 1)
    |> Enum.map(fn _ ->
      List.duplicate(nil, cols)
    end)
  end

  defp set_chars_to_fence(fence, chars, pos_in_zigzag) do
    chars
    |> Enum.with_index()
    |> Enum.reduce(fence, fn {char, index}, acc ->
      rail_ind = Enum.at(pos_in_zigzag, rem(index, length(pos_in_zigzag)))
      List.update_at(acc, rail_ind, &List.update_at(&1, index, fn _ -> char end))
    end)
    |> List.flatten()
    |> Enum.filter(&(&1 != nil))
  end
end

Version data entries

69 entries across 69 versions & 1 rubygems

Version Path
trackler-2.2.1.180 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.179 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.178 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.177 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.176 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.175 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.174 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.173 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.172 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.171 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.170 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.169 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.167 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.166 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.165 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.164 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.163 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.162 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.161 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.160 tracks/elixir/exercises/rail-fence-cipher/example.exs