Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Getting combinations from a number's digits

by PerceptiveJohn (Acolyte)
on Jul 09, 2006 at 23:51 UTC ( #560034=perlquestion: print w/replies, xml ) Need Help??
PerceptiveJohn has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks: New To Perl. Accepting a field from a form that is a 3 digit number.

In the Perl script I would like to store the 6 possibilites these 3 numbers could have in 6 different variables.  Example: If 123 was entered, the 6 different combinations would be 123,132,213,213,312,312. Again, I would like to store each one in a different variable. Would an array be the thing to use and/or what would be a simple loop to create all 6 combinations?

Thank you.

2006-07-10 Retitled by planetscape, as per Monastery guidelines

( keep:1 edit:11 reap:0 )

Original title: 'Newbe- Arrays'

Replies are listed 'Best First'.
Re: Getting combinations from a number's digits
by Zaxo (Archbishop) on Jul 10, 2006 at 01:17 UTC

    Generally, this is a combinatorial problem and there are modules to handle that. Here's another way which is only practical due to the small length of the entry. I run the combinations through hash keys to uniquify them. The regex match serves to both extract the digits and validate the input.

    #!/usr/bin/perl -w # filename: combo use strict; my $entry = shift; my @array = $entry =~ m/^(\d)(\d)(\d)$/ ? ($1.$2.$3, $1.$3.$2, $2.$1.$3, $2.$3.$1, $3.$1.$2, $3.$2.$1) : (); @array or die "Bad input: ${entry}\n"; @array = do { my %hash; @hash{@array} = (); keys %hash; }; print "${entry} was entered.", " The different combinations would be @{array}.\n"; __END__ $ perl combo 123 123 was entered. The different combinations would be 231 123 312 321 2 +13 132. $ perl combo 122 122 was entered. The different combinations would be 221 212 122.

    You will be better off with an array instead of distinct named variables. It will accomodate the smaller number of combinations that are possible with duplicated digits, and you don't have to make up meaningful names for unmeaningful distinctions. (Yes, @array and %hash are not meaningful names outside tutorial use ;-)

    After Compline,

      The line after: my @array =, could you explain the $entry line. Thank you.

        Sure. That uses the "trinary operator", which has the form foo ? bar : baz. It tests foo, whatever that may be, for truth. If true the expression evaluates to bar, if false, to baz.

        Here, foo corresponds to a regular expression match with $entry. The regex tests that $entry consists of exactly three digits and captures the three to $1, $2 and $3 by surrounding each digit's slot with parentheses.

        The bar element is an explicit list of combinations using the captured digits, whatever they may be. It will be returned to the @array assignment by the expression if the match succeeded. The "baz" element is an empty list, which goes to the assignment if the match failed.

        It is important to never use the backreference variables $1,$2,... unless the regex match succeeded. The trinary op above complies with that, since the number variables only appear in the true branch.

        The trinary op is documented in perlop. ++bobf for suggesting the link.

        After Compline,

Re: Getting combinations from a number's digits
by GrandFather (Sage) on Jul 10, 2006 at 00:16 UTC

    Most programmers would differentiate between single variables and arrays. If what you want is to store those values in an array then you could do it like this:

    my @array = (123,132,213,213,312,312);

    However that seems a pretty trivial thing to want to do. I suspect this is an XY Problem. How about asking the real question that is bothering you rather than a question pertaining to what you think might be the solution. Showing some code that you have tried would help a lot too.

    DWIM is Perl's answer to Gödel
      I'll try again: I,m accepting a 3 digit number from a form.

      That number has 6 possible 3-digit combinations. I have to know what those 6 3-digit combinations are so that I can take each one and check to see if it's in a MySql data base table and, if so, tell the user what dates each of the 6 combinations appeared.

      It's a lottery table look-up.

      Does this help? We cuurently work in a MicroFocus Cobol environment which allows us to index each digit and manipulate them.

        Ok, that's a better question. Still no code, but maybe this will get you started:

        use warnings; use strict; use Algorithm::Loops qw(NextPermute); my $number = '123'; my @digits = split //, $number; my @array = ($number); # Add the first permutation push @array, join '', @digits while NextPermute (@digits); print "@array";


        123 132 213 231 312 321

        DWIM is Perl's answer to Gödel
        If you have access to change the database, I wonder whether it would be better to store all the numbers sorted (either in the main table, or in a separate table), and then look them up that way. So if the user enters "312", you'd check for "123". Then you're only doing one lookup instead of 6.
Re: Getting combinations from a number's digits
by gloryhack (Deacon) on Jul 10, 2006 at 04:54 UTC
    You might take a look at List::Permutor. Split your string, take the permutations, go away happy.
Re: Getting combinations from a number's digits
by ioannis (Prior) on Jul 10, 2006 at 00:55 UTC
    This solution is based on the combinational powers of glob()
    my $txt = '123'; local $"=','; my @array = glob( "{@{[ split(//,$txt)]}}" x length($txt) ); print Dumper \@array ;

      That glob will also produce 111, 122, etc. Combinations without replacement are needed.

      After Compline,

      um... I learned something. glob() is an actual module. I thought you were using it like we use blah or foo. Thanks, but does this use of glob create the 6 combinations for him? It seems the 6 combinations are hardcoded and he just want to store them somewhere for later use.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://560034]
Approved by GrandFather
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2017-04-28 12:09 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (521 votes). Check out past polls.