blahblah has asked for the wisdom of the Perl Monks concerning the following question:
Please bear with me while I explain how I got in this mess.
I need to make selection list in a CGI program where users can choose the ordering of columns in a table, like 'first, last, suffix' etc. The hitch was users could also choose a shorter option like 'first, last' from the same list.
So, to make a permutation that presented all of the options for one data set was fairly simple with tye's code on Permuting with duplicates and no memory. Originally, I thought I could get the rest of the options by popping the array and passing it to the permute factory again. It didn't take long to realize that this method does not present all options.
For example:
If you pass the permute factory '0 1 2 3' it will give you all the options for '0 1 2 3'. You pop off 3 then pass it again. Now you have all the options for '0 1 2', but not a single one of those options has 3 in it. So, it turns out you need to pass unique permute seeds:
0 1 2
0 1 3
0 2 3
1 2 3
Only then will you truely have all the permutations.
So, I wrote this permute seed generator. It is supposed to take an array of arbitrary length and generate all the unique permute seeds. Right now it works on arrays that are less than 5 in length, but dies on arrays larger than 5.
I've Super Searched my brains out and pored over this for days. How can I fix this code so that it actually works on arrays of arbitrary length??
#!/usr/bin/perl -w use strict; #how many options should be presented at minimum? my $minpermutelength = $ARGV[0]; #this will be set to 0..$#array_passed_in when all is working my @slots = (0..4); my $biggestslotnum = $#slots; die("Minimum permute length $minpermutelength is larger than the data +set of 0..$#slots\n") if ($minpermutelength > $#slots); die("Minimum permute length cannot be negative or undefined.\n") if ($ +minpermutelength < 0 || !defined $minpermutelength); my $loop = 0; my $iteration = 0; my $thispermute = $#slots; while ($#slots >= $minpermutelength) { while ($slots[$#slots] <= $biggestslotnum) { for (@slots) { print "$_" }; print " loop: $loop iteration: $ite +ration thispermute: $thispermute\n"; # record $slots[$#slots]++; } $slots[$#slots]--; # fix overage from while above if ($slots[$#slots] == $biggestslotnum && $slots[0] == $biggestslot +num - $#slots && $loop == 0) { $thispermute--; # shrink permute string by one @slots = (0..$biggestslotnum); # reset splice(@slots,$thispermute-$biggestslotnum); # 0 1 2 3 $iteration = 0; next; } if ($slots[$#slots-$iteration-1] == $slots[$#slots-$iteration]-1) { + # 0 3 4 $loop = 0; $iteration++; $slots[$#slots-$iteration-1]++; # I think my problem is in these splices, but I can't figure it +out. :( if ($slots[$#slots-$iteration] - $slots[$#slots-$iteration-1] > +1) { splice(@slots,$slots[$#slots-$iteration-1],$thispermute); splice(@slots,@slots,0,$slots[$#slots-$iteration-1]+1..(($slo +ts[$#slots-$iteration-1]+1)+($thispermute-@slots))); $slots[$#slots]++ while ($slots[$#slots] <= $slots[$#slots-1] +); $iteration = 0; } } else { $loop++; $slots[$#slots-1]++; #increase the slot to the left by one $slots[$#slots] = $thispermute + $loop unless ($slots[$#slots-1] + == $slots[$#slots]-1); # start counting again $slots[$#slots]++ while ($slots[$#slots] <= $slots[$#slots-1]); } }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Permutation seed generator
by kvale (Monsignor) on May 06, 2004 at 05:57 UTC | |
by dimar (Curate) on May 06, 2004 at 15:17 UTC | |
by blahblah (Friar) on May 06, 2004 at 06:19 UTC | |
by kvale (Monsignor) on May 06, 2004 at 06:33 UTC | |
by benizi (Hermit) on May 07, 2004 at 21:20 UTC | |
|
Re: Permutation seed generator (again)
by tye (Sage) on May 06, 2004 at 06:14 UTC | |
|
Re: Permutation seed generator
by oha (Friar) on May 06, 2004 at 11:44 UTC | |
|
Re: Permutation seed generator
by Your Mother (Archbishop) on May 06, 2004 at 20:37 UTC | |
|
Re: Permutation seed generator
by Anonymous Monk on May 06, 2004 at 17:46 UTC |