Macro for generating combos of variable length from a given collection

In an earlier AOC thread @LostKobrakai posted the following code for generating pairs from a collection:

combinations =
        for a <- options, b <- options, uniq: true do
          [a, b] |> Enum.sort() |> List.to_tuple()
        end

I am not familiar at all with writing macros in elixir, but I think it would be possible to have a macro that took an argument k such that you could have

combinations =
        for a <- options, b <- options, ... k <- options, uniq: true do
          *stuff*
        end

Is this possible? If so, any tips or suggested resources to look into?

You do not need macros for that, just function would do. What you need to notice is that combinations with size N are combinations of size N-1 and other elements. So you can do similarly to my solution

  def run([], _, _), do: nil
  def run(_, _, sum) when sum < 0, do: nil
  def run([a | _], 1, a), do: [a]

  def run([a | rest], n, sum) do
    case run(rest, n - 1, sum - a) do
      nil -> run(rest, n, sum)
      nums when is_list(nums) -> [a | nums]
    end
  end

You just need to replace addition with generating lists and this will result in what you want.

I can provide more complete example later as right now I am on my phone, so it is hard to code something like that.

1 Like

That‘s only possible if you know ˋkˋ at compile time. If it‘s dynamic at runtime macros won‘t help.

2 Likes

Thanks for clarifying.