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

Re (tilly) 1: (Golf) Strings-to-Array

by tilly (Archbishop)
on Mar 30, 2001 at 09:17 UTC ( #68282=note: print w/ replies, xml ) Need Help??


in reply to (Golf) Strings-to-Array

I had to rename the function, but I get 38. It would be shorter, but I added 3 chars to make it run under 5.6, and added 2 more for a bug fix. Plus the obligatory 5 for a private variable.

So if I was a careless lout, I could claim 28, but I am not...

sub r {my$s;$s.=chop for@_=@_;$s.0?(&r,$s):()}

UPDATE
D'oh. MeowChow is right. I need the private variable.


Comment on Re (tilly) 1: (Golf) Strings-to-Array
Download Code
Re: Re (tilly) 1: (Golf) Strings-to-Array
by MeowChow (Vicar) on Mar 30, 2001 at 12:18 UTC
    If you were a lout, the most you could claim is 33, because a private $s variable is mandatory in the recursive case.

    Though I do believe you've reached par for this course.

Re: Re (tilly) 1: (Golf) Strings-to-Array
by jorg (Friar) on Mar 30, 2001 at 15:46 UTC
    tilly would you care to explain it as well at the risk of me producing this type of code on my next project?

    Jorg

    "Do or do not, there is no try" -- Yoda
      Please don't produce this kind of code except in fun.

      But since you ask, the trick is recursion. Here it is broken out:

      sub r { my $s; $s .= chop for @_ = @_; $s . 0 ? ( &r , $s ) : () }
      and now with better variable names, fewer implicit variables, rewritten loops, that kind of thing:
      sub recursive_s2a { my $str_last; foreach my $str (@_ = @_) { $str_last .= chop($str); } if ($str_last . 0) { return (recursive_s2a(@_) , $str_last ); } else { return; } }
      And now you see that the function creates the last string in the list to produce, tests whether that was the empty string, if it was it returns nothing, if it wasn't it then proceeds by recursion to generate the first strings, and adds the string it produced to that list.
Re: Re (tilly) 1: (Golf) Strings-to-Array
by demerphq (Chancellor) on Sep 01, 2001 at 04:56 UTC
    So if I was a careless lout, I could claim 28, but I am not...
    sub r {my$s;$s.=chop for@_=@_;$s.0?(&r,$s):()}

    Tilly, I have tested your line as follows
    sub r {my$s;$s.=chop for@_;$s?(&r,$s):()} #0 1 2 3 3 #123456789012345678901234567890123 # jeff,john,mary # jjm,eoa,fhr,fny
    on v5.6.1-AS628. and it worked fine.

    I suppose I am missing something, but I dont see what.
    Why are you doing @_=@_ and $s.0??
    Is this an issue for an earlier version of perl? As far as I understand these are redundant ops. When does $s.0 evalute in a boolean sense different to $s? And what is the point of assigning @_ to itself?
    I am confused.

    OTOH it does mean that you can claim 5 less chars, for a total of 33.
    :-)
    Or am I being a lout?

    Yves

      In Perl 5.6.0 if you passed in literal strings, you got an error about, "Modification of a read-only value attempted". Recopying @_ fixed that.

      And the time when $s and $s.0 are different in boolean context is when $s is "0". So when you remove those two characters, you get a bug.

      UPDATE
      An example that shows the bug:

      print map "$_\n", r("0a1", "b0", "0");
        Hmm, and I reran it with literal params (I was using an @array) and I got that warnings as well. Interesting. OST. It follows from the fact @_ alises not copies, but still somehow surprising.

        And it is also very interesting to learn that '00' evals to true. Definitely *not* what I expected. I was thinking that it would fall under the evals to 0 rule, but now I see not. Thanx.

        On the other hand I tested a bunch of cases with 0's in them and I couldnt see how it affected the solution?

        Yves

        Hi Tilly.

        Ok so on that input it doesnt work.

        I guess now I'm being a pain, but japhy's spec *did* say make a function that takes any number of equal-length strings

        However I do believe in defensive programming, so I can see why you did that.

        Very interesting, and food for thought

        Yves

        $\="\n"; $,=","; print r("0000", "0000", "0000"); #outputs #000,000,000,000

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://68282]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (12)
As of 2014-07-14 14:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (262 votes), past polls