How can I get permutations of a list?

前端 未结 5 2025
梦如初夏
梦如初夏 2020-12-10 04:55

How can I get permutations of a list in Elixir?

Eg, for [\"a\", \"b\", \"c\"], I would expect:

# [[\"a\", \"b\", \"c\"], [\"a\", \"c\",          


        
5条回答
  •  旧时难觅i
    2020-12-10 05:42

    I’d put this code here for the sake of discoverability.

    defmodule P do
      defmacro permutations(l, n) do
        clause =
          fn i -> {:<-, [], [{:"i#{i}", [], Elixir}, l]} end
        return =
          Enum.map(1..n, fn i -> {:"i#{i}", [], Elixir} end)
        Enum.reduce(1..n, return, fn i, acc ->
          {:for, [], [clause.(i), [do: acc]]}
        end)
      end
    end
    
    defmodule T do
      require P
    
      def permute3(list), do: P.permutations(list, 3)
    end
    

    It uses plain AST to return the nested list comprehensions.

    T.permute3 ~w|a b|  
    #⇒ [
    #    [[["a", "a", "a"], ["b", "a", "a"]],
    #     [["a", "b", "a"], ["b", "b", "a"]]],
    #    [[["a", "a", "b"], ["b", "a", "b"]],
    #     [["a", "b", "b"], ["b", "b", "b"]]]
    #  ]
    

    It would require more effort to make it possible to pass n through as a parameter, because of early Range expansion, but it’s still doable.

提交回复
热议问题