Skip to content

Latest commit

 

History

History
199 lines (153 loc) · 4.05 KB

multiple_data_structure_recursion.livemd

File metadata and controls

199 lines (153 loc) · 4.05 KB

Multiple Data Structure Recursion

Zip

Example Solution
defmodule Zip do
  def zip(list1, list2, acc \\ [])
  def zip(_, [], acc), do: Enum.reverse(acc)
  def zip([], _, acc), do: Enum.reverse(acc)

  def zip([head1 | tail1], [head2 | tail2], acc) do
    zip(tail1, tail2, [{head1, head2} | acc])
  end

  def zip_many(lists, acc \\ []) do
    if [] in lists do
      acc
      |> Enum.reverse()
      |> Enum.map(&List.to_tuple/1)
    else
      heads = Enum.map(lists, &hd/1)
      tails = Enum.map(lists, &tl/1)

      zip_many(tails, [heads | acc])
    end
  end
end
defmodule Zip do
  @doc """
  Zip two lists together.

  iex> Zip.zip(["a", "b", "c"], [1, 2, 3])
  [{"a", 1}, {"b", 2}, {"c", 3}]

  Ignore trailing elements.

  iex> Zip.zip(["a", "b", "c"], [1, 2, 3, 4])
  [{"a", 1}, {"b", 2}, {"c", 3}]

  iex> Zip.zip(["a", "b", "c", "d"], [1, 2, 3])
  [{"a", 1}, {"b", 2}, {"c", 3}]
  """
  def zip(_list1, _list2) do
  end

  @doc """
  Zip any number of lists together

  iex> Zip.zip_many([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
  [{1, 4, 7}, {2, 5, 8}, {3, 6, 9}]

  Ignore trailing elements.

  iex> Zip.zip_many([[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]])
  [{1, 4, 7}, {2, 5, 8}, {3, 6, 9}]
  """
  def zip_many(_lists) do
  end
end

Frequencies

Example Solution
defmodule Frequencies do
  def frequencies(list, acc \\ %{}) do
    case list do
      [head | tail] ->
        frequencies(tail, Map.update(acc, head, 1, fn count -> count + 1 end))

      [] ->
        acc
    end
  end

  def many_frequencies(lists, acc \\ %{})
  def many_frequencies([], acc), do: acc

  def many_frequencies(lists, acc) do
    frequency_map = increment_frequencies(lists, acc)
    non_empty_tails = get_non_empty_tails(lists)

    many_frequencies(non_empty_tails, frequency_map)
  end

  defp increment_frequencies(lists, acc) do
    Enum.reduce(lists, acc, fn
      [], acc ->
        acc

      list, frequency_map ->
        increment_map(frequency_map, hd(list))
    end)
  end

  defp get_non_empty_tails(lists) do
    Enum.reduce(lists, [], fn
      [], acc -> acc
      list, acc -> [tl(list) | acc]
    end)
  end

  defp increment_map(map, key), do: Map.update(map, key, 1, fn count -> count + 1 end)
end
defmodule Frequencies do
  @doc """
  Count the frequencies of every element in a list.

  iex> Frequencies.frequencies([1, 1, 1, 2, 3, 3])
  %{1 => 3, 2 => 1, 3 => 2}
  """
  def frequencies(_list) do
  end

  @doc """
  Count the frequencies of every element in many lists until all lists are empty.

  iex> Frequencies.many_frequencies([[1, 1, 1, 2, 3, 3], [1, 1, 2], [1]])
  %{1 => 6, 2 => 2, 3 => 2}

  iex> Frequencies.many_frequencies([[1, 1, 1, 2, 3, 3], [1, 1, 2], [1, 2, 3]])
  %{1 => 6, 2 => 3, 3 => 3}

  iex> Frequencies.many_frequencies([])
  %{}
  """
  def many_frequencies(_lists) do
  end
end

Nested Traversal

Example Solution
defmodule NestedLists do
  @doc """
  Traverse nested data lists and flatten them.

  iex> NestedLists.flatten([[1, 2, 3], [4, 5]])
  [1, 2, 3, 4, 5]

  # iex>  NestedLists.flatten([[1], [], [1]])
  # [1, 1]

  # iex>  NestedLists.flatten([[1, [2, [3]], 4], [5]])
  # [1, 2, 3, 4, 5]
  """
  def flatten(lists, acc \\ [])
  def flatten([], acc), do: Enum.reverse(acc)

  def flatten([head | tail], acc) do
    if is_list(head) do
      flatten(head) ++ flatten(tail, acc)
    else
      flatten(tail, [head | acc])
    end
  end
end
defmodule NestedLists do
  @doc """
  Traverse nested data lists and flatten them.

  iex> NestedLists.flatten([[1, 2, 3], [4, 5]])
  [1, 2, 3, 4, 5]

  # iex>  NestedLists.flatten([[1], [], [1]])
  # [1, 1]

  # iex>  NestedLists.flatten([[1, [2, [3]], 4], [5]])
  # [1, 2, 3, 4, 5]
  """
  def flatten(lists) do
  end
end