Think about Loose Coupling PerlMonks

### Golf: ROT-n

by hardburn (Abbot)
 on Nov 09, 2004 at 16:19 UTC 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
[download]```

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

```tr/A-Z/N-ZA-M/;
[download]```

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@_ [download]```

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 [download]```

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 [download]```

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
----
|}~
[download]```

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

```print chr(((ord()+\$n-ord('a'))%26)+ord('a'))for@_
[download]```

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 [download]```
52 strokes

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

Update:  ```# 1 2 3 4 5 # 3456789 123456789 123456789 123456789 123456789 1234567890 print chr 97+(\$ARGV[0]+7+ord)%26for pop=~/./g [download]```
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 (Chancellor) 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 [download]```
 ```# 345678 1 2345678 2 2345678 3 2345678 4 2345678 y//-za/cfor(\$_=pop)x+pop;print (that's \001 as start of the range) [download]```
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' [download]```

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 [download]```

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' [download]```
--
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 [download]```

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 ; [download]```

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 (Pope) 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.
[download]```

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 [download]``` Length 38 ```1234567890123456789012345678901234567890 \$_=pop;y/a-z/b-za/for\$x(1..pop);print [download]``` 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("
[download]```

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
Node Status?
node history
Node Type: perlmeditation [id://406374]
Approved by atcroft
Front-paged by grinder
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (11)
As of 2018-03-22 11:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
When I think of a mole I think of:

Results (273 votes). Check out past polls.

Notices?