Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Code Shortening (golf) [RESOLVED]

by Young Monk (Novice)
on Oct 18, 2010 at 18:41 UTC ( #866017=perlquestion: print w/ replies, xml ) Need Help??
Young Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all. I was trying a question in SPOJ. Let me explain the question first. The input will be a single line containing capital and small letters. Lets assume the following:
Capital Letters-Opcode
Small Letters-Operands
In AbcdEf,
A is an opcode. The operands of A are b,c and d. Similarly, E is an opcode and its operands are f. The opcodes must be moved to the closest upper index that is a multiple of 4.

So, AbcD must be Abc-D, where '-' means a blank (output is 1).
Similarly, ABC must be A---B---C, so the output is 6.
Similarly, AbcdeF must be Abcde---F, so the output is 3.
The task is, to find the minimum number of '-'s that are needed to be inserted to align the Opcodes accordingly.

Here is my solution to this task:
RESOLVED
It is 42 chars long and its the second shortest. The first shortest is 39 chars long. Can u pls try to make it shorter?

Edit: http://www.spoj.pl/problems/NOP/
Edit2: Corrected a small typo. (thanks to Ken)

Comment on Code Shortening (golf) [RESOLVED]
Download Code
Re: Code Shortening (golf)
by toolic (Bishop) on Oct 18, 2010 at 18:54 UTC
    Save 2 by changing print to say.

    A link to whatever site you're looking at would be handy.

      But for using "say", we must include a line before the script like "use 5.10" rite? (not quite sure about the version)
        If you write a one-liner, using -E instead of -e enables the new features like say.
        Perl 6 - links to (nearly) everything that is Perl 6.
Re: Code Shortening (golf)
by moritz (Cardinal) on Oct 18, 2010 at 19:43 UTC
    If you're allowed to use command line options like -n and -E:
    $ echo EaEbFabG | perl -nE'$n+=~y///c&3for/(.*?)[A-Z]/g;say$n-3' 5
    Perl 6 - links to (nearly) everything that is Perl 6.
Re: Code Shortening (golf)
by kcott (Abbot) on Oct 18, 2010 at 19:57 UTC
    Similarly, AbcdeF must be Abcde(NOP)(NOP)F, so the output is 2.

    Shouldn't that be: Similarly, AbcdeF must be Abcde(NOP)(NOP)(NOP)F, so the output is 3.

    Using hyphens instead of (NOP)s:

    012345678
    Abc-D
    A---B---C
    Abcde--F
    Abcde---F
    

    It may just be a typo. If not, I haven't understood the task.

    -- Ken

Re: Code Shortening (golf)
by eyepopslikeamosquito (Canon) on Oct 18, 2010 at 20:55 UTC

    My general golfing advice is to try to use $\ as the accumulator if you possibly can because you can then print it with a bald print.

    For example, this one is six strokes shorter and gives the same result as yours for the three test cases given at the spoj web site:

    $\+=~y///c&3for<>=~/([a-z]+)/g;print
    Don't know if it's generally valid though.

      It will fail for a test case like AB for which, it must be A---B, (ie) output is 3.
      In my solution, decrementing 3 from the result is necessary. So, a bald 'print' cant be used! Any suggestions?

        So, a bald 'print' cant be used!
        To be a competitive golfer you have to be tenacious, devious and challenge assumptions. So I wouldn't rule out using a bald print just yet. At least, not without first trying to find a way to adjust your algorithm so that it can be used.

        For example, why do you subtract 3 at the end, as in print$n-3? Is that to compensate for adding 3 when you (always) match at start of string? If so, you could try to eliminate the need to subtract 3 by adjusting your regex to not match at start of string.

        In any case, I suggest you study every line of perlre looking for something, anything, that might help you shave a stroke. That is the attitude required to win at golf.

Re: Code Shortening (golf)
by aquarium (Curate) on Oct 19, 2010 at 22:42 UTC
    i like this puzzle/question.
    how about just looking up the position of each capital letter (discounting first one), to see that the position aligns with modulus 4. totally untested proof of concept code below
    $n+=4-len($`)%4 for(/[A-Z]/g);print $n-4;
    maybe wiser monks (with access to perl) could try or comment.
    the hardest line to type correctly is: stty erase ^H
      Actually, my solution is similar to yours. The elongated solution is:
      $n+=3-length($_)%4 for<>=~/(.*?)[A-Z]/g;print$n-3

      Lately, I found out about the bit-wise operator '&' and substituted it.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://866017]
Approved by Marshall
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2015-07-07 04:17 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