Rubyでnext_permutation

STLのソースの丸写しだが。

class Array
  def swap_at(i, j)
    self[i], self[j] = self[j], self[i]
  end
  def reverse_in(first, last)
    return if first == last
    last -= 1
    while first < last
      swap_at(first, last)
      first += 1
      last -= 1
    end
  end
  def next_permutation
    return false if self.size < 2
    i = self.size - 1
    loop do
      i -= 1
      if self[i] < self[i + 1] then
        j = self.size - 1
        while not self[i] < self[j]
          j -= 1
        end
        swap_at(i, j)
        reverse_in(i + 1, self.size)
        return true
      end
      if i == 0 then
        reverse_in(0, self.size)
        return false
      end
    end
  end
  def permutation!
    self.sort!
    yield self
    while next_permutation
      yield self
    end
  end
  def permutation
    self.dup.permutation! do |a|
      yield a
    end
  end
end