Randomize

Hello,

I'm looking for a command that will shuffle/randomize file contents to create all possible variants.

example:
school store watches

output
school store watches
watches store school
store watches school



Thank you
faithless1Asked:
Who is Participating?
 
sjklein42Connect With a Mentor Commented:
permute.pl:


@words = @ARGV;

my $level = (-1);
my @Value;
my $N = @words; ## count


sub printIt
{
    my @out;
    for (my $i = 0; $i < $N; $i++)
    {
        push @out, $words[$Value[$i]-1] ;
    }

    print join(" ", @out) . "\n";
}

sub visit
{
    my $k = shift(@_);
    $level = $level+1;
    $Value[$k] = $level;

    if ($level == $N)
    {
        printIt();
    }
    else
    {
        for (my $i = 0; $i < $N; $i++)
        {
            if ($Value[$i] == 0) {  visit($i); }
        }
    }
    $level = $level-1;
    $Value[$k] = 0;
}


for (my $i = 0; $i < $N; $i++)
{
    $Value[$i] = 0;
}
visit(0);

Open in new window



c:\temp>perl permute.pl school store watches
school store watches
school watches store
store school watches
watches school store
store watches school
watches store school

c:\temp>

Open in new window

0
 
APNFSSCCommented:
#! /usr/bin/perl -w

use strict;

my @array = @ARGV ? @ARGV : qw/school store watches/;

sub fac {
   my $nr = shift;
   return 1 if $nr < 2;
   return $nr*fac($nr-1);
}

my %seen;
my $max = fac(scalar @array);
my $nr  = 0;
while( $nr < $max ) {
    my $need_combo = 1;
    my @combo;
    while( $need_combo ) {
        for( my $i = 0; $i < scalar @array; ++$i ) {
            $combo[$i] = $array[ rand scalar @array ];
        }
        my %unique;
        my $unique = 1;
        for my $c ( @combo ) {
            if( ++$unique{$c} > 1 ) {
                $unique = 0;
            }
        }
        if( $unique == 1 ) {
            $need_combo = 0;
        }
    }

    if( exists $seen{ "@combo" } ) {
        next;
    }
    else {
        local $" = " ";
        print "@combo\n";
    }
    ++$seen{"@combo"};
    ++$nr;
}

Open in new window


result is:

school watches store
school store watches
watches store school
store watches school
watches school store
store school watches

0
 
ozoCommented:
see
perldoc -q shuffle

But I'm confused because your example does not create all possible variants.
it misses
store school watches
watches school store
and
school watches store
and if you really want all possible variants, then is sounds more like you want to use Algorithm::Permute
rather than to randomize/shuffle

0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
farzanjCommented:
Do you mean you want to create all permutations?

Like for

a b c

You will have
a b c
a c b
b a c
b c a
c a b
c b a
Right?
0
 
sjklein42Connect With a Mentor Commented:
c:\temp>c:\$\lib\permute.pl how now brown cow
how now brown cow
how now cow brown
how brown now cow
how cow now brown
how brown cow now
how cow brown now
now how brown cow
now how cow brown
brown how now cow
cow how now brown
brown how cow now
cow how brown now
now brown how cow
now cow how brown
brown now how cow
cow now how brown
brown cow how now
cow brown how now
now brown cow how
now cow brown how
brown now cow how
cow now brown how
brown cow now how
cow brown now how

c:\temp>

Open in new window

0
 
faithless1Author Commented:
Thanks for all the responses. Going to test with what seems to be the easiest solution

Ozo -

I ran the perldoc -q shuffle and here's what I see:

use List::Util 'shuffle';

               @shuffled = shuffle(@list);

The command I then used is:

cat file.txt |  perl -pe List::Util

I also ran perldoc -q shuffle but can't seem to figure out what command to use.

Thanks

0
 
faithless1Author Commented:
sjklein42

How would I specify a file with keywords? Would I run the code this way?

perl -pe permute.pl file.txt

Thanks
0
 
faithless1Author Commented:
APNFSSC:

Can you please provide usage details for your script so I can test it as well?

Thank you
0
 
APNFSSCCommented:
what will the contents of file.txt be?

Will it have multiple lines?

0
 
APNFSSCCommented:
Here is an example as the code stands now. You just pass the words to that you want to the script and it does the rest. if you pass nothing then the words 5 of the script are used.

# ./test.pl the quick brown fox
quick brown the fox
fox the brown quick
fox brown quick the
quick brown fox the
fox the quick brown
quick fox brown the
the quick brown fox
brown quick fox the
quick the brown fox
quick the fox brown
the brown fox quick
brown fox the quick
fox quick the brown
the fox brown quick
the quick fox brown
fox brown the quick
fox quick brown the
brown the fox quick
the brown quick fox
quick fox the brown
brown quick the fox
brown the quick fox
brown fox quick the
the fox quick brown

If you give the structure of your file and what you expect to happen then I'll alter the code to read the file in.
0
 
sjklein42Commented:
Lots of ways to skin a cat.

To run my version so it takes the words from an input file. replace the first line with this:

$words = join(' ',<>);
$words =~ s/[\r\n]//g;
$words =~ s/^\s+//;
$words =~ s/\s+$//;
@words = split(/\s+/, $words);

Open in new window


This will use all the words in the input keyword file, whether they are on one line or many.

Run it like this:

perl permute.pl keywords.txt
0
 
APNFSSCCommented:
I'm wondering if the file could be,

this is the first text to jumble
this is the second text to jumple and needs to be kept seperate to first text
this is the third text

will wait for response rather than jumping to conclusions.
0
 
faithless1Author Commented:
Thanks,

APNFSSC:

The file will have records on each line (length varies some rows have sentences others 3-5 words, no set format)

word word word word
word word word

0
 
APNFSSCCommented:
will there be any punctuation in the sentences? like question marks or full stops?
0
 
faithless1Author Commented:
I removed them all, just phrases sentences. thanks
0
 
APNFSSCCommented:
this works but I've noticed that as the amount of words get's longer it's quite slow, you may be better off with sjklein42 or ozo's suggestions. I only tested with a small amount of words originally.

so give it a go with your data and see.

Just run it and pass the filename that you want to pass in.

#./test.pl filename.txt

#! /usr/bin/perl -w

use strict;

if( -e "$ARGV[0]"){
        my $infile=$ARGV[0];
        # you have passed a file to the script let's process that
         open(INFILE, "$infile") || die "Error opening input $infile: $!";
                while (<INFILE>){
                        chomp($_);
                        my $line = $_;
                        my @array = split(/ /, $line);
                        process_array(@array);
                }
}else{
        my @array = @ARGV ? @ARGV : qw/school store watches/;
        process_array(@array);
}

sub fac {
   my $nr = shift;
   return 1 if $nr < 2;
   return $nr*fac($nr-1);
}

sub process_array {
my @array = @_;
my %seen;
my $max = fac(scalar @array);
my $nr  = 0;
while( $nr < $max ) {
    my $need_combo = 1;
    my @combo;
    while( $need_combo ) {
        for( my $i = 0; $i < scalar @array; ++$i ) {
            $combo[$i] = $array[ rand scalar @array ];
        }
        my %unique;
        my $unique = 1;
        for my $c ( @combo ) {
            if( ++$unique{$c} > 1 ) {
                $unique = 0;
            }
        }
        if( $unique == 1 ) {
            $need_combo = 0;
        }
    }

    if( exists $seen{ "@combo" } ) {
        next;
    }
    else {
        local $" = " ";
        print "@combo\n";
    }
    ++$seen{"@combo"};
    ++$nr;
}
}

Open in new window

0
 
APNFSSCCommented:
oh dear.... my bad I forgot to close the file... on my server it works quick until 6 words. then it's slow.

 
#! /usr/bin/perl -w

use strict;

if( -e "$ARGV[0]"){
        my $infile=$ARGV[0];
        # you have passed a file to the script let's process that
         open(INFILE, "$infile") || die "Error opening input $infile: $!";
                while (<INFILE>){
                        chomp($_);
                        my $line = $_;
                        my @array = split(/ /, $line);
                        process_array(@array);
                }
            close(INFILE);
}else{
        my @array = @ARGV ? @ARGV : qw/school store watches/;
        process_array(@array);
}

sub fac {
   my $nr = shift;
   return 1 if $nr < 2;
   return $nr*fac($nr-1);
}

sub process_array {
my @array = @_;
my %seen;
my $max = fac(scalar @array);
my $nr  = 0;
while( $nr < $max ) {
    my $need_combo = 1;
    my @combo;
    while( $need_combo ) {
        for( my $i = 0; $i < scalar @array; ++$i ) {
            $combo[$i] = $array[ rand scalar @array ];
        }
        my %unique;
        my $unique = 1;
        for my $c ( @combo ) {
            if( ++$unique{$c} > 1 ) {
                $unique = 0;
            }
        }
        if( $unique == 1 ) {
            $need_combo = 0;
        }
    }

    if( exists $seen{ "@combo" } ) {
        next;
    }
    else {
        local $" = " ";
        print "@combo\n";
    }
    ++$seen{"@combo"};
    ++$nr;
}
}

Open in new window

0
 
sjklein42Connect With a Mentor Commented:
This version takes an input file as you described and permutes the words on each line:

# usage:   perl permute.pl input.txt

my @words;
my $level;
my @val;
my $N;

sub permute
{
    my $k = shift(@_);
    $level = $level+1;
    $val[$k] = $level;

    if ($level == $N)
    {
        my @out;
        for (my $i = 0; $i < $N; $i++) { push @out, $words[$val[$i]-1] ; }
        print join(" ", @out) . "\n";
    }
    else
    {
        for (my $i = 0; $i < $N; $i++) { if ($val[$i] == 0) { permute($i); } }
    }

    $level = $level-1;
    $val[$k] = 0;
}


while ( <> )
{
    s/[\r\n]//g;
    s/^\s+//;
    s/\s+$//;
    @words = split(/\s+/);

    $level = (-1);
    $N = @words; ## count

    for (my $i = 0; $i < $N; $i++) { $val[$i] = 0; }
    permute(0);
}

Open in new window

0
 
APNFSSCCommented:
sjklein42's code is much faster than mine I would use his.
0
 
ozoCommented:
Could you clarify whether you want a random shuffle, or all permutations?
And, if you have a line that repeats the same word, would swapping those words be  considered a different permutation or not?
0
All Courses

From novice to tech pro — start learning today.