lib/algorithms/insertionsort.ex

defmodule Insertionsort do
  @moduledoc """
	Documentation for `Insertion sort` algorithm. All important
  informations about counting sort you can find at
  [Wikipedia](https://en.wikipedia.org/wiki/Insertion_sort) page.

	### Annotations
	 - n - number of elements in list
	"""

  @doc """
  Sort list
   - Worst-case performance: O(n^2)
   - Average performance: O(n^2)
   - Best-case performance: O(n) - for already sorted or empty lists

  ## Examples

      iex> Insertionsort.run([4, 1, 3, 2])
      [1, 2, 3, 4]

      iex> Insertionsort.run([-7, 0, 0, -2, -3, 5, 2])
      [-7, -3, -2, 0, 0, 2, 5]

  """
  @spec run(list(integer)) :: list
  def run(unsorted) when is_list(unsorted), do: run_with_sorted(unsorted, [])

  defp run_with_sorted([], sorted), do: sorted
  defp run_with_sorted([h | t], sorted), do: run_with_sorted(t, insert(h, sorted))

  defp insert(element, []), do: [element]
  defp insert(element, sorted) when element < hd(sorted), do: [element | sorted]
  defp insert(element, [h | t]), do: [h | insert(element, t)]

end