http://qs1969.pair.com?node_id=77203

OK, I was going thru a ROM dump last week, and text I was interested in was interlaced between the high and low ROMS. Naturally, I thought perl would be ideal to straighten this mess out. The resulting program I wrote felt too long. So, without further ado, your golf course today is to take 2 strings:
Ti sats. hsi et
... and produce a single string from them:
This is a test.
Extra credit: Make the routine split the single string into substrings that're an arbitrary length, and spit them out on separate lines, ie: the big string is really a bunch of strings of "x" bytes.

I promise this ain't homework, even tho it really looks like it by now. :o)

--
Me spell chucker work grate. Knead grandma chicken.

Replies are listed 'Best First'.
Re: (golf) Interlaced Strings
by japhy (Canon) on May 02, 2001 at 07:16 UTC
    Answers of varying lengths:
    sub interlace { # 52 my$x=pop;my$y=reverse+pop;$x=~s/./chop($y).$&/esg;$x } sub interlace { # 47 my$x=pop;@_=split//,pop;$x=~s/./shift.$&/esg;$x } sub interlace { # 45 ($_,@_)=(pop,split//,pop);s/./shift.$&/esg;$_ }
    The last two suffer a mandatory 'shift without parens' warning.

    Update: here's a shorter one, without said warning.

    sub interlace { # 43 $_=shift;@_=split//,pop;s/./$&.shift/esg;$_ }


    japhy -- Perl and Regex Hacker
Re: (golf) Interlaced Strings
by jmcnamara (Monsignor) on May 02, 2001 at 13:42 UTC

    Strange. Nobody used bitwise or. The following is 41 chars:
    sub R1{ $_=sub{join"\0",split//,pop};"\0".&$_|&$_ }

    This is 37 chars but would clobber a subroutine called "_":
    sub R2{ sub _{join"\0",split//,pop}"\0".&_|&_ }

    This is 33 chars but doesn't preserve case:
    sub R3{ sub _{join$",split//,pop}$".&_|&_ }


    John.
    --

      Nice. You can save 2 chars on these by replacing:
      split//,pop
      with
      pop=~/./g # or just 1 char if you put in the 's' modifier
         MeowChow                                   
                     s aamecha.s a..a\u$&owag.print
Re: (golf) Interlaced Strings
by MeowChow (Vicar) on May 02, 2001 at 10:46 UTC
    39 chars under strict, if we're violating perlvars...
    sub j { ($_,$@)=@_;s/./$&.substr$@,0,1,''/ge;$_ }
       MeowChow                                   
                   s aamecha.s a..a\u$&owag.print
Re: (golf) Interlaced Strings
by Chmrr (Vicar) on May 02, 2001 at 07:18 UTC
    I apparently just beat out premchai21, the current leader, by one character:
    #!/usr/bin/perl -w use strict; print j('Ti sats','hri et'),"\n"; sub j { my($a,$b)=@_;$a=~s/(.)/$1.substr($b,length($`),1)/ge;return$a; }

    62 characters.

    Update: Same basic idea as japhy had, but worse execution. Ahh, well.

    Update 2: After seeing japhy's code, I can whittle it down to 40 chars. All credit for the idea goes to japhy, though:

    sub j { $_=pop;@_=split//,pop;s/./shift.$&/eg;$_ }

     
    perl -e 'print "I love $^X$\"$]!$/"#$&V"+@( NO CARRIER'

Re: (golf) Interlaced Strings
by premchai21 (Curate) on May 02, 2001 at 07:00 UTC
    #!/usr/bin/perl use strict; sub interlace { ### ENGAGE GOLF MODE ### my@a=@_;my$z='';($z=chop($a[0]).chop($a[1]).$z)while($a[0]||$a[1]) +;$z ### DISENGAGE GOLF MODE ### } print interlace 'Ti sats.', 'hsi et ';

    69 chars with strict on, according to Emacs.

    Update: D'oh! Changed something and forgot to change the other part to match. Now is six characters longer.

      Do you even need to define @a? I think you can drop this by 7 characters more...
      Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
        Eight, you mean. But I do need to define it; since I'm passing in constants, @_ is considered read-only.

      Am I missing something? This doesn't work for me. $x and $y are never defined. Do you mean:

      my@a=@_;my$z='';($z=chop($a[0]).chop($a[1]).$z)while($a[0]||$a[1]);$z
Re: (golf) Interlaced Strings
by Masem (Monsignor) on May 02, 2001 at 07:05 UTC
    For the main part: 75 char in the sub: (4 less if you don't mind uninit'd values)
    #!/usr/bin/perl -w use strict; my $a = "Ti sats."; my $b = "hsi et"; my $c = j( $a, $b ); print $c."\n"; sub j { my@a=split//,shift;my@b=split//,shift;return join'',map{$_,shift@b||'' +}@a; }

    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain