Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting all possible string combinations with Perl

Tags:

perl

Given a string for example 'rogerdavis' than it should convert it to 'rogerd@vis' or 'rogerdav!s' or 'rogerdavi$' or 'rogerd@v!$' and all possible combination and append it in a file. So basically have to convert 'a' to '@', 's' to '$' and 'i' to '!' and use all possible combinations. This is to be done in Perl.

Pseudocode

  • Create a new file
  • Calculate number of occurrences of a,A,s,S,i,I (or we can accept keyword only in small or in caps to simplify the switch case)
  • Calculate total number of possibilities we can have by using formula of combinations For total number of possibilities we perform the job on hand of replacing character a ->@, s->$, i-> I
  • add unique entry to the file

This is what came to my mind at first. Please help me because I know there's got to be an easy and simple way to do this thing:

  1. Accept keyword in an array keyword[ ]
  2. Calculate length of the array in length_of_keyword
  3. Scan array keyword[ ] from left to right count =0; for(i=0; i }
  4. Using count to calculate total number of possibilities

    total_poss =0;
    r= 1;
    new_count = count
    for (i = count; i > 0; i--)
    {
        // fact( ) will calculate factorial
        total_poss += fact(new_count)/(fact(r)*fact(new_count - r))  
        r++;
     }
    
    for (k=0; k<total_poss; total_poss++)
       copy array keyword[ ] in temporary array temp[ ];
       for (i=0; i< new_count; i++)
       {
    
           for (j = 0; j< lenght_of_keyword; j++)
           {
               if (temp[i] is equal to 'a' || 'A' || 's' || 'S' || 'i' || 'I' )
               {
                   switch (temp[j])
    
                       case i: tempt[i] = ! ;
                                  if ( modified array is equal to an entry in file)
                                      continue;
                                  else save in file; break;
                       case I: (same as above or we can have function for above code)
                     .
                     .// similarly for all cases
                     .
            }
        }
    }
    
like image 292
Lihos Avatar asked Dec 16 '22 10:12

Lihos


1 Answers

I wanted to give List::Gen a whirl. This problem provided the perfect excuse!


use strict;
use warnings;
use List::Gen;

my %symbol = ( a => '@', A => '@',
               i => '!', I => '!',
               s => '$', S => '$', );  # Symbol table

my $string = 'rogerdavis';
my @chunks = split /(?<=[ais])|(?=[ais])/i, $string;

# Turn into arrayrefs for cartesian function

@chunks = map { $_ =~ /^[ais]$/i ? [ $_, $symbol{$_} ] : [ $_ ] } @chunks;

my $cartesian = cartesian { join '', @_ } @chunks;  # returns a generator

say for @$cartesian;  # or 'say while < $cartesian >'

Output

rogerdavis
rogerdavi$
rogerdav!s
rogerdav!$
rogerd@vis
rogerd@vi$
rogerd@v!s
rogerd@v!$
like image 177
Zaid Avatar answered Dec 22 '22 00:12

Zaid