Perl Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesPerl Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old March 1st, 2013, 01:11 PM
midget2000x midget2000x is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2001
Posts: 19 midget2000x User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 40 m 52 sec
Reputation Power: 0
Multiple Permutation handling

I'm trying to figure out some code that will loop thru pre-defined lists and output all combinations (concatenations). Specifically of shirts and size/color/etc options.

For example, here are some lists:



My code needs to output something like this:

SKU1TSBLU
SKU1TSGRN
SKU1TSWHT
SKU1TSBLK
SKU1TMBLU
SKU1TMGRN
SKU1TMWHT
SKU1TMBLK
...
SKU5H2XWHT
SKU5H2XBLK

So basically every combination of every option for each sku.

I have been doing some looping and can get there in a very ugly, inefficient manner, but I just know there's an easier way.

Any help appreciated.

Reply With Quote
  #2  
Old March 1st, 2013, 04:43 PM
Laurent_R Laurent_R is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jun 2012
Posts: 550 Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level) 
Time spent in forums: 5 Days 3 h 26 m 28 sec
Reputation Power: 406
Can you tell us why is your manner ugly and inefficient? Please show us the code.

If you really need all the combinations, then you really have to bite the bullet and generate all of them, one way or another

You can do that yourself, with for example four nested foreach loops, which is not necessarily that ugly and inefficient. For example, the following is rather clean, straight forward and easy to understand:

Perl Code:
Original - Perl Code
  1. foreach my $s1 (@set1) {
  2.      foreach my $s2 (@set2) {
  3.           foreach my $s3 (@sizes) {
  4.                foreach my $s4 (@colors) {
  5.                     print "$s1$s2$s3$s4\n";
  6.                }
  7.          }
  8.      }
  9. }


You could probably "hide" some of the work by a clever multiple use of the map function, or by using some form of recursive descent through the arrays (for example, a recursive call to an iterator function going through the arrays and expanding the return list on each call), but I am not sure the code would be much shorter or easier to read, and it would also probably not be really more efficient.

Then, you have the easy way: you can also hide almost all the work by using a CPAN module such as Algorithm::Combinatorics.

Reply With Quote
  #3  
Old March 2nd, 2013, 12:07 AM
midget2000x midget2000x is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2001
Posts: 19 midget2000x User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 40 m 52 sec
Reputation Power: 0
That's actually perfect. Thanks so much.

Reply With Quote
  #4  
Old March 3rd, 2013, 05:10 PM
Laurent_R Laurent_R is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jun 2012
Posts: 550 Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)Laurent_R User rank is Lieutenant Colonel (40000 - 50000 Reputation Level) 
Time spent in forums: 5 Days 3 h 26 m 28 sec
Reputation Power: 406
Hi Midget,

I just copy here below part of my post in answer to your cross post of your question on Perl Monks forum.

As I said, I think the four nested foreach loops I suggested above is probably the best solution: clean, straight forward, easy to understand and efficient.

For the fun of it, however, let me suggest a kind of "Schwartzian" solution, which could also be called a "Lisp written in Perl" solution (or Scheme, or Haskell, or whatever functional language written in Perl):

Perl Code:
Original - Perl Code
  1. my @sku = qw/SKU1 SKU2 SKU3/;
  2. my @tslh = qw/t s l h/;
  3. my @colors = qw/BLU GRN WHT BLK /;
  4. my @sizes = qw / S M L XL 2X /;
  5.  
  6. print map { $col = $_; map { $siz = $_; map {$a1 =$_; map "$_ $a1 $siz $col\n", @sku;} @tslh} @sizes } @colors;


(I have added spaces between the fields to make the output easier to read.) This prints (I copy only the beginning and the end of the 240-line printout):

Code:
SKU1 t S BLU
SKU2 t S BLU
SKU3 t S BLU
SKU1 s S BLU
SKU2 s S BLU
SKU3 s S BLU
SKU1 l S BLU
SKU2 l S BLU
(...)
SKU2 s 2X BLK
SKU3 s 2X BLK
SKU1 l 2X BLK
SKU2 l 2X BLK
SKU3 l 2X BLK
SKU1 h 2X BLK
SKU2 h 2X BLK
SKU3 h 2X BLK


The beauty (and fun) of this solution is of course that it holds in just one line of code (in pure Perl, without using a module to do the work behind the scene).

There are a number of downsides to this solution, however: first, it is far less easy to understand, it is actually hardly readable. Even though I just wrote it, I am not sure how I would explain it to make it clearly understandable.

To tell the truth, it was also a bit complicated for me to write it: it took me about 3 minutes to write the foreach nested loops above (which I did not even need to test), and and it took me slightly more than half an hour to get the nested map function calls to work correctly. So, in brief, this was just for the fun, I do not recommend this solution.

Last edited by Laurent_R : March 3rd, 2013 at 05:16 PM.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesPerl Programming > Multiple Permutation handling

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap