Method: Immutable::List#permutation

Defined in:
lib/immutable/list.rb

#permutation(length = size) {|list| ... } ⇒ self, Enumerator

Yields all permutations of length n of the items in the list, and then returns self. If no length n is specified, permutations of the entire list will be yielded.

There is no guarantee about which order the permutations will be yielded in.

If no block is given, an Enumerator is returned instead.

Examples:

Immutable::List[1, 2, 3].permutation.to_a
# => [Immutable::List[1, 2, 3],
#     Immutable::List[2, 1, 3],
#     Immutable::List[2, 3, 1],
#     Immutable::List[1, 3, 2],
#     Immutable::List[3, 1, 2],
#     Immutable::List[3, 2, 1]]

Yields:

  • (list)

    Once for each permutation.

Returns:

  • (self, Enumerator)


1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
# File 'lib/immutable/list.rb', line 1097

def permutation(length = size, &block)
  return enum_for(:permutation, length) if not block_given?
  if length == 0
    yield EmptyList
  elsif length == 1
    each { |obj| yield Cons.new(obj, EmptyList) }
  elsif not empty?
    if length < size
      tail.permutation(length, &block)
    end

    tail.permutation(length-1) do |p|
      0.upto(length-1) do |i|
        left,right = p.split_at(i)
        yield left.append(right.cons(head))
      end
    end
  end
  self
end