An initial naïve solution:
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 ) ];
Output:
ABCD
ABC
AB
A
B
AC
C
BC
ABD
AD
D
BD
ACD
CD
BCD
ABCE
ABE
AE
E
BE
ACE
CE
BCE
ABCFG
ABCF
ABF
AF
F
BF
ACF
CF
BCF
ABCG
ABG
AG
G
BG
ACG
CG
BCG
ABFG
AFG
FG
BFG
ACFG
CFG
BCFG
Both the implementation and the algorithm can surely be improved.
Update: The code block now returns a value. This allows the option to skip, as desired.
Update: Slightly modified to attain your ultimate goal.
Update: (Bug fix) Added sort.
Update: I can't think of another algorithm. This will likely be my last solution.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|