Recursive combinations with GenServer
Intuition\nMake recursive combinations, since Elixir has no loops. Then make GenServer to serve requests.\n\n# Approach\nMake unittests, then make recursive com
# Intuition\nMake recursive combinations, since Elixir has no loops. Then make GenServer to serve requests.\n\n# Approach\nMake unittests, then make recursive combinations, then wrap it with GenServer.\n\n# Complexity\n- Time complexity:\nI dunno\n\n- Space complexity:\nI dunno\n\n# Code\n```\ndefmodule CombinationIterator do\n  use GenServer\n\n  @spec init_(characters :: String.t, combination_length :: integer) :: any\n  def init_(characters, combination_length) do\n    GenServer.start(__MODULE__, nil, name: __MODULE__)\n    GenServer.call(__MODULE__, {:reset, Combinatorics.combine(characters |> String.codepoints(), combination_length) |> Enum.to_list()})\n  end\n\n  @spec next() :: String.t\n  def next() do\n    GenServer.call(__MODULE__, {:next})\n  end\n\n  @spec has_next() :: boolean\n  def has_next() do\n    GenServer.call(__MODULE__, {:has_next})\n  end\n\n  @impl true\n  def init(init_arg), do: {:ok, init_arg}\n  @impl true\n  def handle_call({:has_next}, _from, []), do: {:reply, false, []}\n  def handle_call({:has_next}, _from, state), do: {:reply, true, state}\n  def handle_call({:next}, _from, []), do: {:reply, "", []}\n  def handle_call({:next}, _from, [x | state]), do: {:reply, Enum.join(x, ""), state}\n  def handle_call({:reset, state}, _from, _), do: {:reply, nil, state}\n\nend\n\n\ndefmodule Combinatorics do\n  def combine(xs, k) when is_integer(k) and k>=0 do\n    xs = xs |> Enum.to_list()\n\n    do_combine(xs, k)\n    |> Stream.filter(&(Enum.count(&1) == k))\n  end\n\n  defp do_combine([], _k), do: [[]]\n  defp do_combine(xs, 1), do: xs |> Stream.map(&[&1])\n\n  defp do_combine([x | xs], k) do\n      do_combine(xs, k - 1)\n      |> Stream.map(&[x | &1])\n      |> Stream.concat(do_combine(xs, k))\n  end\nend\n\n```
['Elixir']