Sha256: 0b3be7af97f85d21dc8c9c07eaabdf04918f10eb724989ed5bfde64b55c36b05

Contents?: true

Size: 1.52 KB

Versions: 327

Compression:

Stored size: 1.52 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

327 entries across 327 versions & 1 rubygems

Version Path
trackler-2.2.1.109 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.108 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.107 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.106 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.105 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.104 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.103 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.102 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.101 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.100 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.99 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.98 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.97 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.96 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.95 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.94 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.93 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.92 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.91 tracks/elixir/exercises/rail-fence-cipher/example.exs
trackler-2.2.1.90 tracks/elixir/exercises/rail-fence-cipher/example.exs