cataclismic_user has asked for the wisdom of the Perl Monks concerning the following question:

Dear Perl Monks,

I am a novice of Perl. My question is rather simple: how can I generate all permutations of a set of characters, with a given length, in an computationally efficient manner?

To further explain my conundrum: I have a large list of elements such as O=C(O)C(N)CCC/N=C(\N)N, O=C(N)C[C@H](N)C(=O)O, O=C(O)[C@@H](N)Cc1cncn1 and so on. I want to generate all possible permutations, including repetitions of these strings, in a given length (for ex. 6).

Thank you in advance!

Replies are listed 'Best First'.
Re: all permutations of given lenght
by Eily (Monsignor) on Aug 11, 2020 at 07:55 UTC

    Algorithm::Combinatorics probably has what you want (probably not a permutation though, since it would be the same length as the input, without introducing repetitions). Either variations_with_repetition or combinations_with_repetition should be what you're looking for. The first one considers (A, B, B), (B, A, B), and (B, B, A) to be three different solutions (so produces the three), while the second will only produce (A, B, B) and consider the other two to be identical.

      Many thanks! variations_with_repetitions has done the job nicely!
Re: all permutations of given lenght
by Corion (Patriarch) on Aug 11, 2020 at 07:24 UTC

    Maybe you want Algorithm::Loops::NextPermute ? You can give it lists of lists of characters and it will spit out strings (well, lists) of the combinations:

    my @characters = (qw(C N N N N N )); my @list= sort ; do { usePermutation( @list ); } while( NextPermute( @list ) );

    ... or maybe the NestedLoops function is more it - I'm not sure if you also want to generate strings with 2C 4N and so on, and what other characters come into play.

    If there are only two characters coming into play, generating all permutations is equivalent to counting from 1..2**$number_of_characters_in_target_string and interpreting that number as binary, a 1 is "use that character" and a 0 means "use the other character".

Re: all permutations of given lenght
by Anonymous Monk on Aug 11, 2020 at 07:55 UTC
      Indeed! I am trying to generate an exhaustive list of SMILES codes, including their repetitions. I have tried
      use strict; use warnings; use Algorithm::Combinatorics qw(permutations); my $strings = [qw(A B C)]; my $iter = permutations($strings, 3); while (my $c = $iter->next) { print "@$c\n"; }

      The problem is that it does not generate things like AAA, BBB, CCC [A, B, C would be the corresponding SMILEs).

        I am trying to generate an exhaustive list of SMILES codes, including their repetitions.
        permutations are reorderings, i.e. samples without replacement. You seem to want all possible samples with replacement, i.e. variations_with_repetition.
Re: all permutations of given lenght
by perlfan (Parson) on Aug 11, 2020 at 09:01 UTC
    Now that you have a module to use, Dominus' Higher Order Perl will probably provide some insights. There are also lots of variations of this question asked and answered here on PM.