Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re^2: Perl Golf idea

by tobyink (Abbot)
on Apr 30, 2012 at 22:51 UTC ( #968174=note: print w/ replies, xml ) Need Help??


in reply to Re: Perl Golf idea
in thread Perl Golf idea

Nice. I've managed to knock off twelve characters though...

  • @_[0] can be replaced with pop. This needs whitespace before it, but it's still shorter. Savings: 1 character.
  • eq can be replaced by the smart match operator, allowing the whitespace around it to be dropped. Savings: 2 characters.
  • Semicolon after sub definition not needed. Savings: 1 character.

Now we've got:

perl -E'sub w{join"",sort pop=~/./g}$w=w pop;($w~~w$_)&&print for<>' . +/dict.txt acert

But, hell, we can go shorter. Let's switch from the join"",... construct with the babycart operator inside an interpolated string... "@{[...]}". Can't remember why I did this - doesn't actually reduce the size of the code, but I think it was necessary for some of the later stuff.

perl -E'sub w{"@{[sort pop=~/./g]}"}$w=w pop;($w~~w$_)&&print for<>' . +/dict.txt acert

Next, we stop passing a parameter to the w function, and use $_ instead. This means that we can take advantage of the fact that regular expressions get applied to $_ by default, giving us massive savings inside the function. Outside the function it's a mixed blessing. We need to assign that pop to $_ giving us a whole new statement. But we don't need to pass anything to w on either of its invocations, and we can drop the parentheses around the smart match comparison.

perl -E'sub w{"@{[sort/./g]}"}$_=pop;$w=w;$w~~w&&print for<>' ./dict.t +xt acert

Those two assignments in the middle started to grind my gears. I figured there must be a way to ditch the semicolon between them... and there is! The w function no longer cares about what parameters it's passed.

perl -E'sub w{"@{[sort/./g]}"}$w=w$_=pop;$w~~w&&print for<>' ./dict.tx +t acert

I could go two characters shorter, but only swapping from print to say which adds unsightly blank lines to the output.

UPDATE: five characters more. Smart match can deal with arrayrefs!

perl -E'sub w{[sort/./g]}$w=w$_=pop;$w~~w&&print for<>' ./dict.txt ace +rt
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'


Comment on Re^2: Perl Golf idea
Select or Download Code
Re^3: Perl Golf idea
by thundergnat (Deacon) on May 01, 2012 at 14:09 UTC

    Umm. Wow. I knew there was room for improvement reduction but... tobyink++

Re^3: Perl Golf idea
by JavaFan (Canon) on May 01, 2012 at 14:57 UTC
    One character less:
    perl -nlE'sub w{[sort/./g]}INIT{$w=w$_=pop}$w~~w&&say' ./dict.txt acer +t
    And if you don't mind the (second) argument getting printed, another 3 chars less:
    perl -nlE'sub w{[sort/./g]}$w||=w$_=pop;$w~~w&&say' ./dict.txt acert
      And if you don't mind the (second) argument getting printed, another 3 chars less:
      perl -nlE'sub w{[sort/./g]}$w||=w$_=pop;$w~~w&&say' ./dict.txt acert

      This one is wrong (only) if the first line of 'dict.txt' contains a valid word (different from arg2).

      example:

      $ cat dict.txt one neo noe bad $ perl -nlE'sub w{[sort/./g]}$w||=w$_=pop;$w~~w&&say' ./dict.txt oen oen neo noe

      First word is missing. Anyway, this is a very beautiful version: ++

      UPDATE: with an extra newline

      perl -E'@a=sort pop=~/./g;say grep@a~~[sort/./g],<>' ./dict.txt acert

      UPDATE2: one char useless

      perl -E'@a=sort pop=~/./g;say grep@a~~[sort//g],<>' ./dict.txt acert

        Nice. Here's one that returns the correct output using a few characters less:

        perl -nE'$w//=pop;[sort$w=~/./g]~~[sort//g]&&print' ./dict.txt acert

        or, two characters less than that, but with an extra newline between each word:

        perl -nE'$w//=pop;[sort$w=~/./g]~~[sort//g]&&say' ./dict.txt acert

        UPDATE: shorter version with correct output:

        perl -nlE'$w//=pop;[sort$w=~/./g]~~[sort//g]&&say' ./dict.txt acert

        or, same length, more efficient:

        perl -nlE'($w//=[sort pop=~/./g])~~[sort//g]&&say' ./dict.txt acert

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (6)
As of 2015-07-07 03:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (87 votes), past polls