Permutation View Source

This is an Elixir package that calculates permutations of enumerables, including combinations, where the order does not matter.

This is implemented as an Elixir Protocol, which helps communiate the difference between permutations and combinations in way that is more familiar to Elixir programmers: the permutations of Lists are true permutations, whereas the "permutations" of MapSets are combinations (because MapSets have no inherent order).

Examples

The output of Permutation.permute/2 is always a MapSet, regardless of the type of data that is evaluated. This is because the possible permutations are not inherently ordered. The members of the outputted MapSet are of the same data type as the input. E.g. the permutation result of a List yields a MapSet of Lists. The permutation result of a MapSet yields a MapSet of MapSets.

The :cardinality option can be specified where only a subset of the original items should be returned.

When a MapSet is permuted, the results are "combinations" where the order of the items is not considered:

iex> mapset = MapSet.new([:paris, :rome, :tokyo, :budapest])
#MapSet<[:budapest, :paris, :rome, :tokyo]>
iex> Permutation.permute(mapset, cardinality: 2)
{:ok,
 #MapSet<[
   #MapSet<[:budapest, :paris]>,
   #MapSet<[:budapest, :rome]>,
   #MapSet<[:budapest, :tokyo]>,
   #MapSet<[:paris, :rome]>,
   #MapSet<[:paris, :tokyo]>,
   #MapSet<[:rome, :tokyo]>
 ]>}

When a List is permuted, this yields true permutations where the order of the items is considered (so there are therefore, more possibilities):

iex> list = [:paris, :rome, :tokyo, :budapest]
iex> Permutation.permute(list, cardinality: 2)
{:ok,
 #MapSet<[
   [:budapest, :paris],
   [:budapest, :rome],
   [:budapest, :tokyo],
   [:paris, :budapest],
   [:paris, :rome],
   [:paris, :tokyo],
   [:rome, :budapest],
   [:rome, :paris],
   [:rome, :tokyo],
   [:tokyo, :budapest],
   [:tokyo, :paris],
   [:tokyo, :rome]
 ]>}

Installation

This package can be installed by adding permutation to your list of dependencies in mix.exs:

def deps do
  [
    {:permutation, "~> 0.1.0"}
  ]
end

See Also

This package would have taken me much longer to write if it weren't for the hard work and helpful explanations of those who went before: