Just Another Perl / Unix Hacker

I entered the following program in the 5th annual Obfuscated Perl Contest, where it won second prize:

@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print

Well, not quite. I wrote the program long before the contest, and then kept it secret for a long time. Then when the contest rules were finally published, my hopes were dashed! The rules specified a limit of 256 characters, and my program, as you see, had been carefully formatted to fit into four lines of 77 characters each, in the style of a usenet signature. The program totaled 312 characters, which was 56 too many. So the program I actually submitted, which won second prize, was a shortened version that is a little less fun.

I think Felix (the contest judge) made a bad judgement, because the winning program was not nearly as confusing as mine---it was actually very simple. If you fixed the indentation, it was quite straightforward. My program is difficult to understand even if you fix it up with good formatting and reasonable variable names. In the solution file I provided, I expanded it in this way, and it still took me about 2500 words to explain what was going on.

(I don't mind that my program didn't win, but I do mind that it was beaten by an unworthy competitor. The judges alluded to another program, submitted in the same category by Philippe Bruhat. According to the judges, Bruhat's entry was 'the Best Ever' but was disqualified for being too long. I would have been proud to lose to Bruhat's entry. It is truly impressive, and deserves to be seen. It runs in Perl and in PostScript so be sure to send it to your printer to see what comes out. Here it is.)

To appreciate my program properly, you really have to run it. Please do that. It will flip you out. (I hope.) You can download the source code if you want to. (The actual contest entry is also available, but I think it is less interesting.)

If you think you understand how this works, ask yourself the following quiz question:

What is @P for? Why does it have the value ".URRUU\c8R"?

If you think you understand this program, but you can't explain @P, then you are mistaken, because @P is the central data structure of the entire program.

Here are the hints that I provided to the contest judges. If you think you've figured out the answer, look at the hints one at a time before you get to the solution. I guarantee that there will be something that you misunderstood.

Hints

Hint 1 | Hint 2 | Hint 3 | Hint 4 | Hint 5 | Hint 6 | Hint 7 | Hint 8 | Hint 9 | Hint 10 | Hint 11

Solution

You'll have more fun if you try to figure out what is going on before you read the solution.

A complete explanation is available

A plain-text version of the explanation is also available

A Note about the Diagrams

(Some people asked.)

The diagrams on the solution page were rendered with the pic diagram program. pic is a preprocessor for troff and was originally written by Brian Kernighan. I used GNU gpic and groff to transform the pic source code into PostScript, then ghostview to transform the PostScript into a PNM file, then pnmcrop and ppmtogif to transform the PNM file into a GIF.

pic is actually a programming language with control flow and variables and all that good stuff. Unfortunately, it doesn't have real functions; only macros, with bizarre substitution semantics. It has no compound data structures, no while loops, and no bit operations. Its for loops only go up, not down. The diagrams I needed to draw have a highly recursive structure. Is it possible to have a recursive macro in pic? I don't know, and I gave up on it after a while.

Fortunately, a better solution was available. Instead of trying to write programs in pic, I wrote a program in Perl to generate straight-line pic output. Instead of letting pic figure out where the boxes should go, I did it in Perl, and then just told pic the exact position of each box and line. The Perl code could be as recursive as I wanted. It sure is a lot easier to write pic programs in Perl than it is to write them in pic!


Return to: Universe of Discourse main page | What's new page | Perl Paraphernalia

mjd-perl-obfuscated@plover.com