class Array def all_perm return yield [] if empty? cur = pop post = [] while cur (self + post).all_perm { |rest| yield rest << cur } post.unshift cur cur = pop end replace post end end if $0 == __FILE__ a = [1, 2, 3, 1] a.all_perm { |s| p s } puts p a end