Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

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 all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2017-10-24 00:51 GMT
Find Nodes?
    Voting Booth?
    My fridge is mostly full of:

    Results (285 votes). Check out past polls.