Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do you get every possible permutation.. 6

Status
Not open for further replies.

travs69

MIS
Dec 21, 2006
1,431
US
permutation may not be the correct word here.. but I'm guessing :)

How do you get every possible 2 part permutation of a list of strings?

ie
@array = qw(5501 5502 5503);
I want
5501 5502
5502 5501
5501 5503
5503 5501
5502 5503
5503 5502

I do not want 5501 5501, 5502 5502, or 5503 5503.

There is a FAQ for something like this but it comes out 3 parts (a b c, a c b, b a c, ect) also if PREX1 reads this his FAQ for that has an error, print $strings[$q] should be print $symbols[$q]


Thanks in advance as always!


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
And to more precise. The current values I am trying to manipulate are actually all hash keys. I can put them into an array first if needed of course but just thought I'd add that.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Still gives the full list x amount wide.. but it let me to this


Which has a combine function which does exactly what I want.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
I might have lied.. I think I'm to stupid to use that module. It makes my head hurt. The default combine function doesn't allow for duplicates (so a,b is the same as b,a).

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
 
Using the your sample data and changing the range to 5001..5003 would return the following.

Code:
5503, 5502, 5501
5502, 5503, 5501
5502, 5501, 5503
5503, 5501, 5502
5501, 5503, 5502
5501, 5502, 5503

I hope that helps.

--Kevin
 
not well tested:

Code:
se List::Permutor;
my @array = qw(5501 5502 5503 5504);
foreach my $i (0..$#array) {
   my $perm = new List::Permutor ($array[0],$array[1]);
   while(my @set = $perm->next) {
      print "One order is @set.\n";
   }
   my $t = shift @array;
   push @array, $t; 
}

of course this could be done easily sans the List::permutor module since all there ever is are two combinations per iteration:

Code:
my @array = qw(5501 5502 5503 5504);
foreach my $i (0..$#array) {
   print "$array[0],$array[1]\n";
   print "$array[1],$array[0]\n";
   push @array, shift @array;; 
}


------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Thanks Travis for pointing out that error.
Tried to solve your problem (and yes your terminology is correct, see Permutation - Wikipedia), but had no success: it's much harder than the combinations n x n.
In doing that I've rewritten the code in the FAQ using strings instead of subarrays: it is muuuch faster, though a little less easy to use for the end user.

Franco
: Online engineering calculations
: Magnetic brakes for fun rides
: Air bearing pads
 
So each row of the array is paired with each other row in the array. How about something like this? (not tested)
Code:
my @array = qw(5501 5502 5503);
foreach my $i (0..$#array) {
   foreach my $j (0..$#array) {
      unless ($i = $j) { print "$array[$i] $array[$j]\n"; }
   }
}

-- Chris Hunt
Webmaster & Tragedian
Extra Connections Ltd
 
Thanks for the help guys.. I'll try these out when I get to work.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
Ewish. Take a look at the data I provide and the output I want to get. No matter how many values I have I only want 2 values in the output.

Stars for everyone cause I've had no sleep!!! :D

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[noevil]
Travis - Those who say it cannot be done are usually interrupted by someone else doing it; Give the wrong symptoms, get the wrong solutions;
 
If you only want the permutations of n elements 2 by 2, then the solution of Chris is OK.
Kevin's solution is incorrect, as it only considers pairs that are adjacent in the starting list.

Franco
: Online engineering calculations
: Magnetic brakes for fun rides
: Air bearing pads
 
Chris's code has a small error in it:

unless ($i = $j)

should be:

unless ($i == $j)


My code indeed does not produce the correct output for lists more than three elements long. It could be made to work but there is no need since Chris's suggestion looks to be more efficient.






------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
A variation that would be a little more efficient on larger lists by removing any 'if' logic and only looping through half the iterations:

Code:
my @array = qw(5501 5502 5503 5504);
foreach my $i (0..$#array-1) {
   foreach my $j ($i+1..$#array) {
      print "$array[$i],$array[$j]\n";
      print "$array[$j],$array[$i]\n";
   }
}
 
I've been playing with this but this doesn't seem to be anything close to what I need. What I see in this thread seems closer.

#!/usr/bin/env perl
use strict;
use warnings;
use List::permutor;

my @data = qw/1 2 A B/;

my %results; #where we'll store each string we find

sub perm {
return unless @_; #base case for recursion is just to exit

my $perm = new List::permutor @_;
while (my @tempresults = $perm->next){
#join each subset into a string, and record it
$results{join '', @tempresults}++;
}

#remove one element at a time from data, and permute the result
for my $i (0 .. $#_){
my @temp = @_;
splice @temp, $i, 1;
perm(@temp);
}
}

#start everything off
perm (@data);

#Get one copy each of each string found.
my @results = sort keys %results;
print "@results\n";
__END__

Basically, the output I'm interested in is;

All possible combinations of 0-9 and A-F in 4 digit sections, of three minimum and of 6 groups maximum.

So, the number starts with
xxxx-xxxx-xxxx
using all possible combinations, then moves on incrementing 2 figits,
xxxx-xxxx-xxxx-xx
then
xxxx-xxxx-xxxx-xxxx
etc up to 6 sections total.
xxxx-xxxx-xxxx-xxxx-xxxx-xxxx

Thanks folks.

Mike
 
then moves on incrementing 2 digits
Please clarify: if you have groups of 4 digits, what is in the 2 digit addition?

Apart from this I understand that:
1)you form all possible combinations of the 16 hex digits in groups of 4
2)then you form all the possible combinations of the 4 digit sequences in 1) into groups of 3
3)as 2) but in groups of 4
4)as 2) but in groups of 5
5)as 2) but in groups of 6
6)The output is the concatenation of 2)+3)+4)+5)
Are you aware that the list produced in 2) contains 8x10[sup]13[/sup] elements, growing to 7x10[sup]27[/sup] elements for the list resulting in 5)? Of course you'll need to select only a specified subsection of those lists.

Franco
: Online engineering calculations
: Magnetic brakes for fun rides
: Air bearing pads
 
mparidis,

I think you're complicating matters by using permutation here. If you're looking to find all permutations of four hex digits, just do something like this:
Code:
foreach my $i (0..65535) {
  printf("%04X",$i);
}
You can nest loops inside eachother to get multiple blocks:
Code:
foreach my $i (0..65535) {
  foreach my $j (0..65535) {
    foreach my $k (0..65535) {
       printf("%04X-%04X-%04X",$i,$j,$k);
    }
  }
}
As prex points out, you're going to get a colossal number of results back as your increase the number of digits.

Have you considered paying for the software and getting a correct key instead?

-- Chris Hunt
Webmaster & Tragedian
Extra Connections Ltd
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top