Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
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 taking refuge in the Monastery: (17)
As of 2014-12-18 21:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (65 votes), past polls