Reputation: 10012
Stupidly, I've forgotten my gpg password.
I know the password is made up of three of six strings connected by a "_".
The possibilites are (let's say) "1", "2", "3", "4", "5" and "6".
Let's say the password is actually "2_5_3".
How to loop through all combinations? There should be no duplicates (i.e. "2_2_4" is not a valid password)!
I'm trying to write this in Perl, but don't really know where to start. Pseudo-code is good.
Many thanks in advance,
UPDATE: OK, I got it working now.
Not as elegant as some of the solutions below...
#!/usr/bin/perl
use strict;
use warnings;
my @possibilities=("111","222","333","444","555","666","777");
my $size=scalar(@possibilities);
print $size."\n";
for(my $i=0;$i<$size;$i++){
for(my $j=0;$j<$size;$j++){
for(my $k=0;$k<$size;$k++){
if($i==$j || $j==$k || $i==$k){
}else{
print $i."_".$j."_".$k."\n";
}
}
}
}
Upvotes: 1
Views: 1148
Reputation: 105905
Basically you need three for loops to iterate over each word (or a multi-index). Since you want to ensure that there aren't any duplicates you have to skip those (Python code):
names = ["abc","def","ghi","jkl","mno","pqr"]
for x in names:
for y in names:
if y in [x]: # word already used?
continue # skip duplicates
for z in names:
if z in [x,y]: # word already used?
continue # skip duplicates
print(x+"_"+y+"_"+z)
UPDATE: Perl code (the very first I've ever written, so I guess it's gross for the Perl developer's eye...)
use strict;
use warnings;
my @words = ("abc","def","ghi","jkl","mno","pqr");
foreach my $w1 (@words){
foreach my $w2(@words){
next if $w1 eq $w2;
foreach my $w3(@words){
next if $w3 eq $w1;
next if $w3 eq $w2;
print $w1.'_'.$w2.'_'.$w3."\n";
}
}
}
Upvotes: 3
Reputation: 91488
Here a way to do it with perl:
my @l = glob "{1,2,3,4,5,6}_{1,2,3,4,5,6}_{1,2,3,4,5,6}";
@l = grep{!/(\d)[_\d]*\1/}@l;
Upvotes: 10