Saturday, January 13, 2007

Quine Hunt 2007

A few weeks ago a co-worker was kind enough to introduce me to the idea of a quine. A quine is a program that produces its complete source code as its only output. Note that programs which take input are not considered quines (so no reading your source).

For fun, I challenge the readers here to produce their own quine: a shorter quine in Java, or a quine of any length in any other programming language. Hint: I think you can use printf to make this shorter. And if you search the Internet for your answer then you are a CHEATER. A Cheater I say!

Here was the quine my co-worker produced:

public class Replicant { private static final String quote = new String(new byte[]{34}); private static final String self ="public class Replicant { private static final String quote = new String(new byte[]{34}); private static final String self =; public static void main(String[] args){ System.out.println( self.substring(0,123) + quote + self + quote + self.substring(123) ); }}"; public static void main(String[] args){ System.out.println( self.substring(0,123) + quote + self + quote + self.substring(123) ); }}

The lack of whitespace is not a formatting error... whitespace in the quine is just extra garbage to try to work around. For a warm-up, I took this basic quine format and removed unnecessary keywords to produce a shorter version. It was definitely an exercise in escape characters and substring methods!

class Replicant { static String quote = new String(new byte[]{34}); static String self ="class Replicant { static String quote = new String(new byte[]{34}); static String self =; public static void main(String[] args){ System.out.println( self.substring(0,88) + quote + self + quote + self.substring(88) ); }}"; public static void main(String[] args){ System.out.println( self.substring(0,88) + quote + self + quote + self.substring(88) ); }}

Just for fun I tried to do this in Perl (it's a fun language, right?). I went round and round on this digging myself deeper and deeper holes. I finally had my a-ha moment when I realized that variable declarations in Perl include the $ sign, which in turn requires an escape character. The Java format of declaring variables will not work in a Perl quine, and a Perl quine needs to be essentially a functional program. I make the slash() and quote() functions and it worked awesome. Here is my Perl quine:

sub slash{chr(92);}sub quote{chr(34);}sub my_substr{substr(self(), $_[0], $_[1]);}sub self{"sub slash{chr(92);}sub quote{chr(34);}sub my_substr{substr(self(), \$_[0], \$_[1]);}sub self{;}print(my_substr(0, 91) . quote() . my_substr(0, 67) . slash() . my_substr(67, 7) . slash() . my_substr(74, 164) . quote() . my_substr(91, 900));";}print(my_substr(0, 91) . quote() . my_substr(0, 67) . slash() . my_substr(67, 7) . slash() . my_substr(74, 164) . quote() . my_substr(91, 900));

It felt so great to accomplish this, especially when the solution turned out to be functional programming. C'mon, let's see your quine. I'll give the shortest Java quine 100 Linden dollars (Lord knows I don't need any SecondLife currency!).

No comments: