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;
 
Why does everyone assume something is bad when someone is interested in something unusual? I wouldn't bother trying to hack a key over a few bucks. It's actually not that mysterious, I just don't really want to post it publicly :).

Anyhow, I've also now become curious about this and find it interesting that such a tiny program can do this.

I have several little programs I've kept over the years once I understood what I could change in them to change the output or use the output in other things.
Not being a programmer, I've got to ask for examples and see things work, then be able to change things a little to get a desired output.

Using a 32bit machine, it seems that I could end up with a very tiny program doing just what I want.

Let me explain the goals as output. I have two little programs I've been given which I'll paste at the end of this post.

The digits being separated are more of a visual thing, no actual need, just easier to see the numbers since I'm used to seeing 4 digits at a time.

The program I originally posted was the first one I'd found and messed with but it's nothing close to what I've wanted as output. These two are closer it seems.

#!/usr/bin/perl
use strict;
use warnings;

my ($num, $fmt);

do {
$fmt = uc join '-', unpack 'A4A4A4', sprintf '%012x', $num++;
print $fmt, "\n";
} until $fmt eq 'FFFF-FFFF-FFFF';
--------------------------------
#!/usr/bin/perl
use strict;
use warnings;
use bigint;

print 2**63-1;

my ($outer, $o_num);
do {
$outer = uc sprintf '%04x', $o_num++;
my ($fmt, $inner, $i_num);
do {
$inner = uc sprintf '%04x', $i_num++;
print "$outer-$inner\n";
} until $inner eq 'FFFF';
} until $outer eq 'FFFF';





 
I've updated my username to reflect my lack of knowledge hehe.
 
>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:

Yes, that's correct, all combinations of various amounts of hex digits, 0-9, a-f. I wanted them in fours because they are easier to see.

foreach my $i (0..65535) {
foreach my $j (0..65535) {
foreach my $k (0..65535) {
printf("%04X-%04X-%04X",$i,$j,$k);

I'm guessing the output for this is; 7B0A0000-000A
But it's coming out as 7B0A0000-000A-7B0A0000-000A continuously.

>As prex points out, you're going to get a colossal number >of results back as your increase the number of digits.

I'm running this stuff on a spare machine so it's no big deal. I don't need to keep the output when done.
What I'd like to see is an output which starts with 12 and works it's way up to 16.
 
Ok, I changed;
printf("\n%04X-%04X-%04X",$i,$j,$k);
to get the desired output.

The output looks similar to one of the codes I posted. Interesting how this can be done in so many different ways to get the same output.

I see it's doing 12 digits so I'll see if I can make it do 16 now. How does one confirm/know that all combinations are in fact being generated, no duplicates? Does anyone ever really know that?

 
Sorry for my own replies :).

I see now, it was easy to add an additional set of digits and to add a line feed.
Interesting. So what other ways could I manipulate these numbers? For example, could I send certain sets to one file, other sets to another?

For example, all output with aaaa-aaaaa-xxxx-xxxx goes into a file called four-fs, another bbbb-bbbb-xxxx-xxxx go into a file called four-bs, etc. Just some ways of manipulating so much output.



 
Just correct the printf as follows:
Code:
printf("%04X-%04X-%04X\n",$i,$j,$k);
And oops, in calculating the figures above I forgot about repetitions: you not only want combinations, but combinations with repetitions. The number becomes 3x10[sup]14[/sup] with three groups, and of course the square of this, or 8x10[sup]28[/sup], with six groups. To give you an idea of what these numbers represent: the age of the universe is not a sufficient time for calculating the latter, even imagining to use a computer zillion times faster than the present ones.
You've not been at all clear on your needs and goals. Anyhow the code you need is as given by ChrisHunt: for 4 groups just add one more foreach loop. And be prepared for being patient: our civilization won't be anymore on the earth when the calculation is complete.


Franco
: Online engineering calculations
: Magnetic brakes for fun rides
: Air bearing pads
 
How does one confirm/know that all combinations are in fact being generated, no duplicates? Does anyone ever really know that?
Let me re-cast the problem for a moment and you'll see what I mean. Supposing you'd asked for all four-digit combinations of the digits 0 to 9. You could get all combinations-and-permutations on the problem, but it really isn't necessary - just count through all the numbers between 0000 and 9999 and you'll have hit all the possible combinations.

What you're effectively asking for is all four (or more)-digit combinations of the hexadecimal digits 0 to F. Counting through all the numbers between 0000 and FFFF does the job (FFFF in hex = 65535 in decimal).

In theory you could get any number of digits you wanted by changing the upper limit - say 000000000000 to FFFFFFFFFFFF. The problem is that sooner or later you'll reach a number that's too large for Perl to handle. The nested loops approach avoids this potential pitfall, and makes it easy to achieve your xxxx-xxxx-xxxx formatting to boot.

I hope you can go without that "spare machine" of yours for a while. When listing out all the 24-digit possibilities, assuming it does one per microsecond (i.e. 1 million per second), it'll take more than 2,500,000,000,000,000 years to complete the program. Even the modest 12-digit version I posted above would take nearly 9 years to complete.

The answer will probably be "42" anyway.

-- Chris Hunt
Webmaster & Tragedian
Extra Connections Ltd
 
As for being clear, it's as clear as it gets, it's just plain interesting, infinite, unreal, etc.

Would it be possible to only use a specific set of numbers rather than 0-9/A-F?
For example, what if I used only 036789ECDF as the seed? How would I enter this to tell the code to use only those digits?

In other words, rather than run the gamut, if I was able to enter a seed of numbers/letters to use, then I would get a smaller result. Still huge I'm sure but a smaller result right?

Mike
 
If you're looking at sets of x digits, where each digit could be one of n different choices, the total number of combinations will be n^x (where ^ means "raised to the power"). For example, the number of 2-digit combinations of the digits 0-9 is 10^2 = 100 (you should note that the number of digits in the combination soon has a greater bearing on the result than the number of choices for each digit).

If the digits you're dealing with are an arbitrary collection instead, you won't be able to use my short cut of just counting through them. You can do it one digit at a time like this:
Code:
@digits = qw(0 3 6 7 8 9 E C D F);
foreach my $i (@digits) {
  foreach my $j (@digits) {
    foreach my $k (@digits) {
       foreach my $l (@digits) {
          print "$i$j$k$l";
       }
    }
  }
}
That just does four digits, you might want to explore some of the libraries mentioned above to save yourself much tiresome typing.



-- Chris Hunt
Webmaster & Tragedian
Extra Connections Ltd
 
I updated what I'm looking for but I can't seem to see it in thie thread now? What I actually need is something I've not explained correctly all along, I thought I was on the right track thinking I could mod the code to get what I need.

What I need is to take a strong of hex and ascii, say 1a2b3c4e, and get all of the possible hex permutations I can out of that, in that order however, not every possible combination out of that order. Does that make sense?

I know what my start and end needs to be and I know that I have x number of segments to achieve so the code needs to work within that constraint.

In other words, say that this is the code, T12b3R4n.

-The code would already be in the right order so no need to do all sorts of other things, just in that order.

-Since the output I need can only be permutations of 0-9/A-F, then I know that T is a given at 54. It means I also know that it ends with 6E.

-The permutations I need come in at 1. The char 1 could be either a 1 or 31. The char 2 could be a 2 or it could be a 32. Same for the b, 3 and 4 using my example above.

-The char n is definitely 6E however.

-I also know that my final number will be between x and x number of digits so the code would have another helping hand knowing that it cannot go smaller or beyond a certain boundary.

I need all of the possible permutations of this combination, in this sequence of digits, output in Hex.

Does this better explain it?
 
I fess up and now the thread ends?

What I actually need turns out to be more interesting, maybe simpler, maybe not, only you know :).

 
I think its safe to assume that only printable characters could be used in the license.

Might be quicker to look up the invoices and documentation that came with it. Or request copies from the supplier.

assume the same is posted on forums.devshed.com

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
I keep telling folks that it's not what I'm up to. I can't be any more honest about it. I reset the configuration on a piece of used hardware, the manufacturer no longer supports it so if I can't get my code back, the hardware is junk.

I have my license since I was able to get a copy of it off the machine before it died but since it was already entered into the registry, it's no longer just plain easy to read hex. Instead, it's mixed in with hex and ascii.

Why doesn't anyone ever believe anyone anymore???
 
I interpret what you explained as follows:
-in your example the 2nd character, '1', could either be the ascii 0x31 or the ascii 0x01
-similarly for '2', 'b', '3', '4'
If this is not correct please post a real exhaustive example.
If this is correct then you have only 32=2[sup]5[/sup] combinations and you can do it by hand on a back of envelope.

Franco
: Online engineering calculations
: Magnetic brakes for fun rides
: Air bearing pads
 
>in your example the 2nd character, '1', could either be the >ascii 0x31 or the ascii 0x01

Correct, but in human readable form as in 1 or 31, no 0x.

>similarly for '2', 'b', '3', '4'

Correct.

>If this is not correct please post a real exhaustive example.

In as far as I've tried to explain it, this is correct.
And there are some givens such as the output can only be 0-9 and A-F and between x number of permutations, 14 to 32 I think it was.

There are also separators in the registry code which means to me maybe they can be used to help the program determine the permutations.

There are also separators which should help the program a great deal also because the output can only be segments of 4 digits of 0-9/A-F. This is not a given however otherwise, I would have done this by now.

So basically, a little program that would take an input something like; Q5\fcS\cLm\cdN for example.

I would know that the start and end numbers are this,
because Q=51, 5=35.

5135-xxxx-xxxx-CD4E

So I would be looking for the 4 digit permutations for fcS\cLm with an output of 0-9/A-F.

>If this is correct then you have only 32=25 combinations >and you can do it by hand on a back of envelope.

I've tried it by hand and it's not working. I think it's possible that segments might not always be 4 digits which is why I need a little code to do this with, change the - position, things like that.

Mike
 
PS: The separators aren't that important, they just make things easier to see. Just the permutations are all that I need.
 
I found the darn code written on a sticker on the back.
I have to say that I've learned some cool things and got some code from some other folks that I'm playing with for the hell of it.

Thread ended, thanks to those who did help.

Later.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top