class MoreMath::Permutation

def self.for_mapping(a, b)

will not be unique.
elements. If these arrays contain duplicate elements, the solution
Both arguments must be the same length and must contain the same
Builds a permutation that maps a into b.
def self.for_mapping(a, b)
  a.size == b.size or
    raise ArgumentError, "Initial and final lists must be the same length"
  lookup = Hash.new { |h, k| h[k] = [] }
  a.size.times { |i| lookup[a[i]] <<= i }
  value = Array.new(b.size) do |i|
    e = b[i]
    lookup[e].pop or raise ArgumentError, "no corresponding element for #{e.inspect}"
  end
  Permutation.from_value value
end