use strict; use warnings; sub r(&$@) { my $cb = shift(@_); my %seen; local *_r = sub { my @v = @_; return if $seen{join $;, @v}++; return if not $cb->(@v); return if @v == 1; for (0..$#v) { my @v_ = @v; splice(@v_, $#v-$_, 1); _r(@v_); } }; _r(sort @$_) foreach @_; } r { print(@_, "\n"); 1 } [ qw( A B C D ) ], [ qw( A B C E ) ], [ qw( A B C F G ) ];