Reputation: 139
I have a set of 15 words, but 3 of them are not needed. I need to get all the combinations. These words are sorted, do not mix them.
I try to remove from the array, but the script reports an error.
@words_orig = qw(Home Pronunciation Symbols Help About Mobile Apps Shop Dictionary API Privacy Policy Terms About2 Contact);
@words = (@words_orig);
for $w1 ( 0 .. $#words ) {
delete @words[$w1];
for $w2 ( 0 .. $#words ) {
delete @words[$w2];
for $w3 ( 0 .. $#words ) {
delete @words[$w3];
print join(' ', @words) . "\n";
@words = (@words_orig);
}
}
}
Upvotes: 0
Views: 60
Reputation: 385839
There should be C(15, 15-3) = (15*14*13)/(3*2*1) = 455 solutions.
That can be found using the following:
for my $i00 (0 .. $#words) {
for my $i01 ($i00+1 .. $#words) {
for my $i02 ($i01+1 .. $#words) {
for my $i03 ($i02+1 .. $#words) {
for my $i04 ($i03+1 .. $#words) {
for my $i05 ($i04+1 .. $#words) {
for my $i06 ($i05+1 .. $#words) {
for my $i07 ($i06+1 .. $#words) {
for my $i08 ($i07+1 .. $#words) {
for my $i09 ($i08+1 .. $#words) {
for my $i10 ($i09+1 .. $#words) {
for my $i11 ($i10+1 .. $#words) {
say "@words[$i00, $i01, $i02, $i03, $i04, $i05,
$i06, $i07, $i08, $i09, $i10, $i11]";
}}}}}}}}}}}}
The above can also be written as follows:
use Algorithm::Loops qw( NestedLoops );
my $iter = NestedLoops([
[ 0..$#words ],
( sub { [ $_+1..$#words ] } ) x ( @words - 3 - 1 ),
]);
while ( my @indexes = $iter->() ) {
say "@words[@indexes]";
}
Note that the provided solutions consider duplicate words to be different words. This should be fine since the OP indicated the presence of a duplicate word was a mistake.
Upvotes: 1
Reputation: 241898
In this case, it's probably better to work with the indices of the words:
#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
my @words = qw( Home Pronunciation Symbols Help About Mobile Apps Shop
Dictionary API Privacy Policy Terms About Contact );
for my $i (0 .. $#words) {
for my $j ($i + 1 .. $#words) {
for my $k ($j + 1 .. $#words) {
say join ' ', @words[ grep $_ != $i && $_ != $j && $_ != $k,
0 .. $#words ];
}
}
}
Note that "About" is mentioned twice, so comparing the words by string comparison would return a different list:
#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
my @words = qw( Home Pronunciation Symbols Help About Mobile Apps Shop
Dictionary API Privacy Policy Terms About Contact );
for my $i (@words) {
for my $j (@words) {
next if $i le $j;
for my $k (@words) {
next if $j le $k || $i le $k;
say join ' ', grep $_ ne $i && $_ ne $j && $_ ne $k, @words;
}
}
}
Upvotes: 1