Challenge: Implement ROT-47 in code that works as both itself and as the ROT-47 version of itself.


Your score is calculated as a percentage of used, ROT-47 eligible bytes in total of both versions of the program divided by total bytes (all characters) of both versions.

A used, ROT-47 eligible byte is any character that would be converted by the ROT-47 cipher that is not part of a comment or ignored by the compiler/interpreter. For example, any character in a brainfuck program that is not +-<>[],. is not considered a used byte, and any character in a C program including and after // or inside /* */ is not considered a used byte. All special symbols in APL are not considered used, as are all characters in a Whitespace program (sorry).

Ties will be broken by the program with the most upvotes. If there is still a tie, then the shortest program wins.

Example scoring:

C: 62/64 = 96.875%

Notice there is a space in this program. Obviously also, this program is not a valid entry because it doesn't even compile, but I wanted to show how scoring works.

main(){printf("Hello World!");}
  • 4
    \$\begingroup\$ And what language does >2:?WXLAC:?E7WQw6==@ (@C=5PQXjN compile in? \$\endgroup\$ – user10766 Mar 3 '14 at 20:51
  • \$\begingroup\$ @hosch250 lol, that was just a dumb example \$\endgroup\$ – durron597 Mar 3 '14 at 20:52
  • 1
    \$\begingroup\$ By "ROT-47 eligible" do you mean "in the ASCII range 33 to 126"? I.e. if my C program has spaces or newlines or tabs, do those count as ROT-47 eligible or not? What about the fact that some spaces are essential in order for a program to function in many languages - do those not count as used because they are not R47-eligible, even though the program would break without them? \$\endgroup\$ – Jonathan Van Matre Mar 3 '14 at 21:06
  • \$\begingroup\$ @JonathanVanMatre The spaces or newlines or tabs don't count because I feel the scoring would be too complicated otherwise; and I don't want Whitespace to be able to score 100%, because that would defeat the purpose. \$\endgroup\$ – durron597 Mar 3 '14 at 21:53
  • 2
    \$\begingroup\$ To everyone who is objecting to my crazy scoring rules, please comment/answer here: meta.codegolf.stackexchange.com/questions/1167/… \$\endgroup\$ – durron597 Mar 4 '14 at 0:40

Ruby, 100% (74 characters)

Input on STDIN, output on STDOUT.


The second line is the first line ROT-47'd. Therefore, when ROT-47ing the whole program, it becomes:


My strategy here is based upon the fact that:

  • V is ' when ROT-47'd

  • j is ; when ROT-47'd

  • Therefore, Vj=...Vj; turns into ';l...';, which is essentially a no-op

    • Now you can create any arbitrary code that does anything normally and no-ops when ROT-47'd. This is because Vj=...Vj; can support running any code as you could do Vj=0;{INSERT ANY CODE};Vj;, and that will become '...'; when ROT-47'd. You just have to be careful not to use V in that code, since that will break it.
  • Similar logic can be used in reverse to produce the second half (jV instead of Vj)

  • \$\begingroup\$ okay you are correct I never specified that and I won't retroactively. However, spaces still do not count as eligible characters; this should be 136/140 I think. \$\endgroup\$ – durron597 Mar 3 '14 at 22:08
  • 1
    \$\begingroup\$ @durron597 Fixed; no more spaces. \$\endgroup\$ – Doorknob Mar 3 '14 at 22:09
  • \$\begingroup\$ Dang ruby not requiring lines to end with a semicolon :) \$\endgroup\$ – durron597 Mar 3 '14 at 22:15

C - 54.6%

Y;BW;XL;jNj;AW(){XL^Y;};main(int i,char**v){char*x=v[1];while(*x){if(*x>32&&*x<128)*x=(*x+15)%94+32;putchar(*x++);}}//Y^Nj>2:?W:?E :[492CYYGXL492CYIlG,`.jH9:=6WYIXL:7WYImbaUUYIk`agXYIlWYIZ`dXThcZbajAFE492CWYIZZXjNN

When ROT-47-translated, we get

*jq(j){j;};jp(WXL){/*jNj>2:?W:?E :[492CYYGXL492CYIlG,`.jH9:=6WYIXL:7WYImbaUUYIk`agXYIlWYIZ`dXThcZbajAFE492CWYIZZXjNN^^*/};main(int i,char**v){char*x=v[1];while(*x){if(*x>32&&*x<128)*x=(*x+15)%94+32;putchar(*x++);}}

Both programs compile, and ROT-47-translate the first argument:

$ ./a "hello world"
96==@ H@C=5
  • \$\begingroup\$ I had trouble getting this to work on ideone. I'm very impressed seeing a score above 50% though! \$\endgroup\$ – durron597 Mar 3 '14 at 22:04
  • \$\begingroup\$ @durron597 It won't work on ideone as it accepts input via arguments, not stdin \$\endgroup\$ – mniip Mar 3 '14 at 22:06
  • 1
    \$\begingroup\$ Upvote for implementing ROT-47 for arguments, not just for self-translation. That should have been in the spec. \$\endgroup\$ – Jonathan Van Matre Mar 4 '14 at 0:26

GolfScript, 120 / 120 bytes = 100%


or, in ROT-47:


No comments or string abuse. The undefined command LiUUbamUUZadckYLfZfZhcTbbZNYNT (which equals the rest of the code in ROT-47) is a no-op, but it still gets executed by the interpreter, so I believe it counts as used.

This was actually a pretty easy challenge in GolfScript. The main difficulty was in avoiding the digit 1, which is mapped by ROT-47 into the GolfScript command `. The commands ., -, ,, \, [, /, ] and ^ also had to be avoided, but that was fairly easy in this case, since the task required no array building.


Here's a GolfScript period-2 quine (i.e. a program that prints a second program that prints the first program again) where the two programs are the ROT-47 transforms of each other:


This program outputs itself ROT-47 encoded, yielding another GolfScript program:


which, in turn, also outputs itself ROT-47 encoded, yielding the previous program again. Thus, this program is also a rotating quine.

  • \$\begingroup\$ Your denominator is wrong: "divided by total bytes (all characters) of both versions". 60/120 = 50% \$\endgroup\$ – Jonathan Van Matre Mar 4 '14 at 0:00
  • \$\begingroup\$ @JonathanVanMatre: All bytes in both versions are used (= executed by the interpreter), so that would be 120 / 120 = still 100%. \$\endgroup\$ – Ilmari Karonen Mar 4 '14 at 0:03
  • \$\begingroup\$ I'm unsure of the scoring because I don't know golfscript. I know that, for example, A in brainfuck would count in the numerator but not the denominator. Is this the same thing or different? \$\endgroup\$ – durron597 Mar 4 '14 at 0:32
  • \$\begingroup\$ @durron597: LiUUbamUUZadckYLfZfZhcTbbZNYNT is a valid identifier in GolfScript, and will be executed as a command. However, it's not one of the built-in commands, nor is it assigned a meaning by the program, so by default it simply does nothing. \$\endgroup\$ – Ilmari Karonen Mar 4 '14 at 0:36

python, 96.1% (?)

According to your definition, strings count as used code?

V=input();print("".join([chr(33+(ord(V[i])+14)%94)for i in range(len(V))]));V
'l:?AFEWXjAC:?EWQQ];@:?W,49CWbbZW@C5WD,:.XZ`cXThcX7@C : :? C2?86W=6?WDXX.XXj'
  • 1
    \$\begingroup\$ In retrospect they shouldn't have, but it's far too late now \$\endgroup\$ – durron597 Mar 3 '14 at 22:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.