Search code examples
fileperlcombinationsargs

In perl how can I generate all possible combinations of numbers contained in a file?


I found locally the following perl code that calculates all possible combinations for chars or numbers but you need to provide them using a qw function my @strings = [qw(1 2 3 4 5 6 7 8 9 10 11 12 13)];, and I need to read these numbers (1 2 3 4 5 6 7 8 9 10 11 12 13) from a file and pass them to the @strings array or pass the numbers via Perl line command arguments to the mentioned @strings array.

I've read all info regarding qw() but I didn't find a way to use it when reading a file of Perl line command arguments, so can you give some advice in order to fix this issue?.

The output provided now is:

1 2 3 4 5
1 2 3 4 6
1 2 3 4 7 ...

Code:

use strict;
use warnings;

#my $strings = [qw(AAA BBB CCC DDD EEE)];
#my $strings = [qw(1 2 3 4 5 6 7 8 9 10 11 12 13)];
my @strings = [qw(1 2 3 4 5 6 7 8 9 10 11 12 13)];

sub combine;

print "@$_\n" for combine @strings, 5;

sub combine {

  my ($list, $n) = @_;
  die "Insufficient list members" if $n > @$list;

  return map [$_], @$list if $n <= 1;

  my @comb;

  for (my $i = 0; $i+$n <= @$list; ++$i) {
    my $val  = $list->[$i];
    my @rest = @$list[$i+1..$#$list];
    push @comb, [$val, @$_] for combine \@rest, $n-1;
  }

  return @comb;
}

Solution

  • First of all, this isn't right:

    my @strings = [qw( 1 2 3 4 5 6 7 8 9 10 11 12 13 )];
    

    That creates an array with a single element, a reference to another array.

    You want

    my @strings = qw( 1 2 3 4 5 6 7 8 9 10 11 12 13 );
    combine \@strings, 5;
    

    or

    my $strings = [qw( 1 2 3 4 5 6 7 8 9 10 11 12 13 )];
    combine $strings, 5;
    

    qw(...) is equivalent to split ' ', q(...), where q(...) is just '...' with a different delimiter.

    This means that

    my @strings = qw( 1 2 3 4 5 6 7 8 9 10 11 12 13 );
    combine \@strings, 5;
    

    is equivalent to

    my @strings = split(' ', ' 1 2 3 4 5 6 7 8 9 10 11 12 13 ');
    combine \@strings, 5;
    

    But of course, we don't need to use single-quotes to construct the string we pass to split; we could use pass a string that was created from reading a file.

    So, the reading-from-file equivalent of

    my @strings = qw( 1 2 3 4 5 6 7 8 9 10 11 12 13 );
    combine \@strings, 5;
    

    would be

    my $line = <>;
    chomp($line);
    my @strings = split(' ', $line);
    combine \@strings, 5;
    

    (The chomp isn't actually necessary because split ' ' ignores trailing whitespace.)