defmodule PrimeFactors do
  @doc """
  Compute the prime factors for 'number'.

  The prime factors are prime numbers that when multiplied give the desired
  number.

  The prime factors of 'number' will be ordered lowest to highest.
  """
  @spec factors_for(pos_integer) :: [pos_integer]
  def factors_for(number), do: do_factors_for(number)

  defp do_factors_for(number, acc \\ [], divisor \\ 2)
  defp do_factors_for(1, acc, _divisor), do: Enum.reverse(acc)
  defp do_factors_for(number, acc, divisor) when rem(number, divisor) == 0 do
    case divisor < trunc(number ** 0.5) + 1 do
      true -> do_factors_for(div(number, divisor), [divisor | acc])
      false -> Enum.reverse([divisor | acc])        
    end
  end
  defp do_factors_for(number, acc, divisor), do: do_factors_for(number, acc, divisor + 1)
end