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

Hello Monks,

I have what is probably a simple problem but can't seem to get my head around it.

My first array looks like this...

my @start = ('dog','cat','bird','mouse','rat','snake','horse','cow','p +ig','lizard','lamb','zebra','lion','elephant','monkey');
I want to create a new array for each element from @start and that has 3 random elements from @start appended to it. I want to end up with something like this...
my @want = ('dog lizard bird lamb', 'cat pig lion monkey', 'bird elephant bird horse', 'mouse cow rat zebra', 'rat snake mouse cat', 'snake pig dog cow', 'horse cat mouse zebra', 'cow monkey cat pig', 'pig bird dog lamb', 'lizard mouse lion dog', 'lamb lion pig zebra', 'zebra monkey bird mouse', 'lion horse snake lizard', 'elephant pig mouse zebra', 'monkey rat bird cat');
Any help or guidance is most appreciated!

Replies are listed 'Best First'.
Re: Array problem
by BrowserUk (Patriarch) on Sep 27, 2008 at 02:33 UTC

    #! perl -slw use strict; use List::Util qw[ shuffle ]; my @start = qw[ dog cat bird mouse rat snake horse cow pig lizard lamb zebra lion elephant monkey ]; my @want = map{ join ' ', $start[ $_ ], ( shuffle @start[ 0 .. $_-1, $_+1 .. $#start ] )[ 0 .. 2 ] } 0 .. $#start; print for @want; __END__ dog cat lamb lizard cat lamb mouse pig bird pig monkey lizard mouse bird pig snake rat dog bird lion snake mouse horse rat horse lion elephant lamb cow lamb horse bird pig cat rat bird lizard bird horse cat lamb rat zebra dog zebra monkey horse snake lion pig zebra dog elephant lamb monkey cow monkey rat lamb snake

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      A slight alternative is to shuffle the indexes.

      my @want = map{ "@start[ $_, ( shuffle 0 .. $_-1, $_+1 .. $#start )[ 0 .. 2 ] ]" } 0 .. $#start;

      Don't even need join anymore!

        But neither are a good solution if the array is large: for each element, you're shuffling (almost) the entire array, just to get three elements. It makes for a quadratic solution, where a linear will do.
      Nice, very nice! And a lot better than my effort, which I won't bother to post having seen BrowserUK's; and more than being nice code, it has the additional quality that the the OPer will, I think, hesitate to turn it in for his homework assignment without doing a lot of digging to figure out just what is going on inside this little gem.
Re: Array problem
by Anonymous Monk on Sep 27, 2008 at 02:22 UTC
    Which part are you having problem with, iterating over the array, or selecting elements at random? Both are easy to do, and are explained in the documentation/faq. Try reading perlintro and perldoc -q random.+?array, maybe even Tutorials
      I guess the problem is the iteration. I get the same exact set of random elements for each element in @start.
Re: Array problem
by llancet (Friar) on Sep 27, 2008 at 06:26 UTC
    Some hint:
    sub extract_randomly { my $n=int rand @begin; my $tmp=$begin[$n]; splice @begin,$n,1; return $tmp; }
      @begin should be @rope :D
Re: Array problem
by jdporter (Paladin) on Sep 28, 2008 at 20:53 UTC
    use List::Util qw(shuffle); use strict; use warnings; my @start = qw( dog cat bird mouse rat snake horse cow pig lizard lamb + zebra lion elephant monkey ); my @a = shuffle @start; for ( 0 .. $#a ) { print "@a[ $_, ($_+1)%@a, ($_+3)%@a, ($_+6)%@a ]\n"; }

    The nice thing about this is that it does exactly one shuffle, and never calls rand (except insided the shuffle).

    Between the mind which plans and the hands which build, there must be a mediator... and this mediator must be the heart.
      Caveat: That can't ever give the results the OP provided.