Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Golf: ROT-n

by hardburn (Abbot)
on Nov 09, 2004 at 16:19 UTC ( [id://406374]=perlmeditation: print w/replies, xml ) Need Help??

A simple (and highly insecure) cipher is to rotate the alphabet by n letters and then substitute. For instance, rotating 13 letters gets you:

plaintext: abcdef ciphertext: nopqrs

This is known as ROT-13. There is a simple solution for ROT-13 in Perl using tr///:

tr/A-Z/N-ZA-M/;

However, this is not easy to generalize to arbitrary rotation numbers.

Your challenge will be to come up with the shortest rotation cipher for an arbitrary number of rotations. The program should take two options on the command line. The first is the rotation number, and the second is a string to encipher. You may assume the first argument will be between 1 and 25, and the second argument will be all lowercase alphabetical characters in ASCII. It must print out the enciphered text on one line (newline not required).

My attempt:

# 1 2 3 4 # 3456789 123456789 123456789 123456789 123456 ($n,$_)=@ARGV;split//;print chr(ord()+$n)for@_

46 strokes. Update: dragonchild points out a bug in this (Doh!).

"There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Replies are listed 'Best First'.
Re: Golf: ROT-n
by tilly (Archbishop) on Nov 09, 2004 at 18:54 UTC
    Fore! 38 strokes...
    #23456789_123456789_123456789_12345678 $_=pop;for$x(1..pop){y/a-z/b-za/}print

    UPDATE: Looking at other solutions inspired an improvement to 36 strokes.
    #23456789_123456789_123456789_123456 $_=pop;eval"y/a-z/b-za/;"x pop;print

      tilly++. Not the most efficient approach, but defiantely one I wouldn't have thought of.

      "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Re: Golf: ROT-n
by dragonchild (Archbishop) on Nov 09, 2004 at 16:31 UTC
    Bug:
    rotn.pl 4 xyz ---- |}~

    It should return 'bcd'. The immediate un-golf'ed fix would be:

    print chr(((ord()+$n-ord('a'))%26)+ord('a'))for@_

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: Golf: ROT-n
by dragonchild (Archbishop) on Nov 09, 2004 at 16:46 UTC
    # 1 2 3 4 5 # 3456789 123456789 123456789 123456789 123456789 1234567890 $n=shift;print chr(($n-97+ord)%26+97)for split//,pop
    52 strokes

    Update:
    # 1 2 3 4 5 # 3456789 123456789 123456789 123456789 123456789 1234567890 print chr 97+($ARGV[0]-97+ord)%26for pop=~/./g
    46 strokes

    Update:
    # 1 2 3 4 5 # 3456789 123456789 123456789 123456789 123456789 1234567890 print chr 97+($ARGV[0]+7+ord)%26for pop=~/./g
    45 strokes, thanks to cLive_;-)

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      Ah, but -97%26 == 7%26 - so there's another character ;-)

      cLive ;-)

        What do you mean?

        Update: Duh! :-)

        Being right, does not endow the right to be rude; politeness costs nothing.
        Being unknowing, is not the same as being stupid.
        Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
        Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: Golf: ROT-n (33)
by eyepopslikeamosquito (Archbishop) on Nov 09, 2004 at 23:19 UTC

    # 345678 1 2345678 2 2345678 3 2345678 4 2345678 y/a-z/b-za/for($\=pop)x+pop;print
      # 345678 1 2345678 2 2345678 3 2345678 4 2345678 y//-za/cfor($_=pop)x+pop;print (that's \001 as start of the range)
Re: Golf: ROT-n
by fruiture (Curate) on Nov 09, 2004 at 17:41 UTC

    I couldn't find a shorter solution for the character-based approach. So this is different, maybe it can be made even shorter than 54.

    # 1 2 3 4 5 # 3456789 123456789 123456789 123456789 123456789 123456789 eval'tr/a-z/'.chr(97+shift).'-za-z/for@ARGV;print pop'

    update: changed spoiler hiding to standard way.

    --
    http://fruiture.de
      Nicely done. I always forget the ins-and-outs of tr///. A few improvements:
      # 1 2 3 4 5 # 3456789 123456789 123456789 123456789 123456789 123456789 $_=pop;eval'y/a-z/'.chr(97+pop).'-za-z/';print

      And you're at 46 strokes

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

        Hot++, i was currently at 50 (or 49) strokes. I never think of tr/// vs y///, though (successfully forgot about y/// for readability).

        # 1 2 3 4 5 # 3456789 123456789 123456789 123456789 123456789 123456789 eval'tr/a-z/'.chr(97+shift).'-za-z/,print for pop'
        --
        http://fruiture.de
Re: Golf: ROT-n
by fruiture (Curate) on Nov 09, 2004 at 16:48 UTC

    I could make it to 37.

    # 1 2 3 # 3456789 123456789 123456789 123456789 print map{chr$ARGV[0]+ord}split//,pop # sadly i could not come up with a split-less soution that # is short enough

    Update: ROT is for ROTate, so this is not a solution to the problem. Working on it...

    Update2: changed HTML to properly hide code

    --
    http://fruiture.de

      ok, solving the problem, 58, or 59 if the ambiguity warning disturbs you.

      # 1 2 3 4 5 # 3456789 123456789 123456789 123456789 123456789 123456789 print map{chr+(($_=$ARGV[0]+ord)>122?-26:0)+$_}split//,pop ; print map{chr((($_=$ARGV[0]+ord)>122?-26:0)+$_)}split//,pop ;

      update: changed hiding code here, too

      --
      http://fruiture.de

      You got hit by the same bug I did. See dragonchild's first response.

      "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Re: Golf: ROT-n
by BrowserUk (Patriarch) on Nov 09, 2004 at 19:03 UTC

    Not shorter (yet) but different. Maybe the approach can be improved?
    
           #        1         2         3         4         5
           #123456789 123456789 123456789 123456789 123456789 
    perl -e"die map{($i)=@ARGV;$_++while$i--;chop}split'',pop" 4 pqrstuvwxyz
    
    tuvwxyzabcd at -e line 1.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
      This generates an error on Perl 5.8.4 (Can't modify constant item in postincrement).

      I thought about a couple of variants of this idea (not this one though) but didn't find a way to get the stroke count low. Particularly not on my version of Perl.

        Strange. The output I showed was using 5.8.4 (AS810)

        [19:39:27.71] P:\test>perl -v This is perl, v5.8.4 built for MSWin32-x86-multi-thread (with 3 registered patches, see perl -V for more detail) Copyright 1987-2004, Larry Wall Binary build 810 provided by ActiveState Corp. http://www.ActiveState. +com ActiveState is a division of Sophos. Built Jun 1 2004 11:52:21 Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using `man perl' or `perldoc perl'. If you have access to + the Internet, point your browser at http://www.perl.com/, the Perl Home Pa +ge. [19:40:24.59] P:\test>perl -e"die map{($i)=@ARGV;$_++while$i--;chop}sp +lit'',pop" 4 pqrstuvwxyz tuvwxyzabcd at -e line 1.

        I saw your for tr version just after I posted which is in a similar vien but much shorter. Nice work++.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: Golf: ROT-n
by borisz (Canon) on Nov 09, 2004 at 20:38 UTC
    1234567890123456789012345678901234567890 $_=pop;for$x(1..pop){y/a-z/b-za/}print
    Length 38
    1234567890123456789012345678901234567890 $_=pop;y/a-z/b-za/for$x(1..pop);print
    Length 37, but does not work, why?
    Boris

    Edited by Chady -- code tags.

      perl -we" $_=pop;y/a-z/b-za/for$x(1..pop);print" syntax error at -e line 1, near "$x("

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
        I know, I asked what is wrong with that line?
        Boris
Re: Golf: ROT-n
by belg4mit (Prior) on Nov 18, 2004 at 09:57 UTC
    Just adding some keywords for Super Search and a link to prior art on caesar/cesar shifts Caesar Shift.

    --
    I'm not belgian but I play one on TV.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://406374]
Approved by atcroft
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2024-04-19 02:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found