Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Mixing up da Arrays (Golf)

by ChOas (Curate)
on Apr 18, 2001 at 17:08 UTC ( #73480=perlquestion: print w/replies, xml ) Need Help??
ChOas has asked for the wisdom of the Perl Monks concerning the following question:

Hey People,

As usual leons and I were coding a bit, and tried
to find a way to mix n number of m lenght arrays
together, preserving the original order of the
original arrays

I came up with this:
#!/usr/bin/perl -w use strict; sub Mix; my @Row1=(1,3,5,7); my @Row2=(2,4,6); my @Row3=(9,9,9); my @Row4=Mix(\@Row1,\@Row2,\@Row3); print "@Row4\n"; sub Mix { my @Result; while(1) { my $Old=@Result; push @Result,grep $_,shift @{$_} for @_; last if @Result==$Old; }; @Result; };
Output: 1 2 9 3 4 9 5 6 9 7

Anyway to do it quicker/more efficient/shorter ?


print "profeth still\n" if /bird|devil/;

Replies are listed 'Best First'.
Re: Mixing up da Arrays (Golf)
by jmcnamara (Monsignor) on Apr 18, 2001 at 18:38 UTC

    This is short but inefficient.
    #!/usr/bin/perl6 sleep(31536000); @Row4 = merge(@Row1, @Row2, @Row3);
    The sleep() is there because we may have to wait a while for merge().

    There are PI seconds in a nano-century.

(tye)Re: Mixing up da Arrays (Golf)
by tye (Sage) on Apr 18, 2001 at 18:02 UTC
Re (tilly) 1: Mixing up da Arrays (Golf)
by tilly (Archbishop) on Apr 18, 2001 at 19:39 UTC
    Do I hear golf?

    First at 48 chars, the one that modifies the original arguments like yours does:

    sub Mix { my@a;@_=grep{@$_?push@a,shift@$_:0}@_ while@_;@a }
    and a safe one that doesn't do that at 59 chars:
    sub MixS { my@a;for(my$i;@_;++$i){@_=grep{$i<@$_&&push@a,$$_[$i]}@_}@a }
Re: Mixing up da Arrays (Golf)
by arhuman (Vicar) on Apr 18, 2001 at 18:44 UTC
    I'll definitly win the 'ugly one' contest with this one...
    Its only advantage : it leaves the arrays passed as arguments untouched, (I feel that someone could make it smaller too)

    The most bothering thing for me (apart from the nasty $i handling)is the stop test :
    last unless (join'',@n)
    Too long, and to weird, anyone to help me improve this ?

    sub Mix2 { my (@r,@n); my $i=-1; while($i++>-2){ @n=map{$_->[$i]}@_; @r=(@r,@n); last unless (join'',@n) } @r; }
    UPDATE :
    To save one char and make it even uglier,
    You can whange while($i++>-2) to while($i+++2)
    (and my $i=-1; to my $i--; for another one)

    "Only Bad Coders Badly Code In Perl" (OBC2IP)
Re: Mixing up da Arrays (Golf)
by kschwab (Priest) on Apr 18, 2001 at 18:24 UTC
    I have no idea if this is quicker or more efficient, but it's uglier:)

    #!/usr/bin/perl -w use strict; sub Mix; my @Row1=(1,3,5,7); my @Row2=(2,4,6); my @Row3=(9,9,9); my @Row4=Mix(\@Row1,\@Row2,\@Row3); print "@Row4\n"; sub Mix { my @Result; for (0..scalar @{(sort {$#{$b} <=> $#{$a}} @_)[0]}) { foreach my $a (@_) { push(@Result,@$a[$_]) if ($_ <= $#{$a}); } } @Result; }
Re: Mixing up da Arrays (Golf)
by little (Curate) on Apr 18, 2001 at 18:04 UTC
    look up Math::Matrix for quick and somewhat magic number manipulation :-)

    Have a nice day
    All decision is left to your taste
Re: Mixing up da Arrays (Golf) (Russ=53)
by Russ (Deacon) on Apr 19, 2001 at 00:22 UTC
    I can get 53 for the safe version (see the post by tilly for details), though with (at least) one terrible inefficiency:
    sub Mix{ map{my$i=$_;map{$$_[$i]}grep{@$_>$i}@_}{@$_}@_ }

    Brainbench 'Most Valuable Professional' for Perl

      What a clever inefficiency! I was trying to find a way to generate a list of numbers that was at least as big as each list, but failed...

      With ?: I can save some, and shaving with map$foo,@list tricks I can save some more. This brings the safe version down to 48 characters.

      sub Mix { map{my$i=$_;map$i<@$_?$$_[$i]:(),@_}$_,@_ }
      That matches what was done unsafely before. But unfortunately for sanity's sake observe the following 33 character entry:
      sub Mix { map{splice@$_,0,1}map@_,map@$_,@_ }
      I have written saner code...

      Saved 3 chars on the unsafe example, there is no need for a nice numerical list when I will be just converting the elements...

      UPDATE 2
      Sheesh. And the safe example can be modified to the rather bizarre 45 character beast:

      sub Mix { map{splice@$_,0,1}map@_,map@$_,@_=map[@$_],@_ }
      UPDATE 3
      I give up on shrinking this. However I have 4 variations on the key 33 char sub. In terms of efficiency of execution, the following wins:
      sub Mix { map{map{splice@$_,0,1}(@_)x@$_}@_ }
      So that is (barring the unexpected) my final answer.
Re: Mixing up da Arrays (Golf)
by premchai21 (Curate) on Apr 18, 2001 at 22:25 UTC
    Not shorter, but more obfuscated:
    sub Mix{map{my$a=$_;map{$$_[$a]}@_}0..Max(map{scalar @$_}@_)} sub Max{my$a=shift;while(@_){my$b=shift;$a=$b if($b>$a)}$a} print Mix([1,2,3,4],[5,6,7],[8,9,0]);

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://73480]
Approved by root
and the fire pops...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (7)
As of 2017-06-27 02:12 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (598 votes). Check out past polls.