Java Quine, Sans Semicolons

Well, if you were looking for a Java program that would print out itself without using any semi-colons, you've found it. But why would someone want to write a program that prints itself out? And why would someone want to program in Java without using semi-colons? Both questions remain mysteries. However, the solution isn't...

mshonle:~/Desktop$ ls -la Quine.java 
-rw-r--r--  1 mshonle  mshonle  5537  3 Jan 17:00 Quine.java
mshonle:~/Desktop$ javac Quine.java 
mshonle:~/Desktop$ java Quine > QuineOutput
mshonle:~/Desktop$ diff Quine.java QuineOutput
mshonle:~/Desktop$ 

The above is just proof for myself that it all works. For you to prove it to yourself, you'll need to copy the below program and compile it and compare the output with your text. (And, for completeness, you should search for semicolons, lest someone think you were a sucker.)

The Shortest Versions (Java 5)

Here is the second shortest version I have here, and in some ways the easiest to understand:

public class SemilessQuine2Point0 {
  public static void main(String[] src) {
    if ((src = new String[] {
"public class SemilessQuine2Point0 {",
"  public static void main(String[] src) {",
"    if ((src = new String[] {",
"",
"    }) == null){}",
"    for (String line: src) {",
"      if (line.length() == 0) {",
"        for (String toQuote: src)",
"          if (System.out.printf((char)34 + toQuote + (char)34",
"               + (char)44 + (char)10) == null) {}",
"      }",
"      else",
"        if (System.out.printf(line + (char)10) == null) {}}}}",
    }) == null){}
    for (String line: src) {
      if (line.length() == 0) {
        for (String toQuote: src)
          if (System.out.printf((char)34 + toQuote + (char)34
               + (char)44 + (char)10) == null) {}
      }
      else
        if (System.out.printf(line + (char)10) == null) {}}}}

And now, I'll make the bold claim here that the following is the shortest Java quine without using semicolons out there (at 258 characters):

public class R{R(String s){if(System.out.printf(s,34,s)==null){}}public static void main(String[]a){if(new R(
"public class R{R(String s){if(System.out.printf(s,34,s)==null){}}public static void main(String[]a){if(new R(%n%c%s%1$c)==null){}}}%n")==null){}}}

You can make it shorter by removing the newlines, but that change itself isn't very interesting.

Update 1: By using printf's 1$ notation, I was able to trim this by 16 characters.
Update 2: Using the constructor trick creates the binding for "s" with slightly fewer characters than a previous version that used a for-each loop. Any further ideas are appreciated.

A Longer Version (Java 5)

The short version is cute, but it uses the raw ASCII codes to avoid quoting hell. This version lives in quoting hell. Its technique is general enough to easily allow for any arbitrary string literal to appear in the program.

Compare this one to the Java 1.4 version below. Because printf is part of Java 5, all of that reflection isn't necessary.

Longest, Craziest Version (Java 1.4)

Now, finally the interesting version! This one even reinvents the looping constructs from the ground up.

public class Quine {
      public static void main(String[] args) {
            if (new GetProgramString(new StringReceiver() {
                  public void receive(String theProgram) {
                        if (new Print(theProgram + "\n\n") == null) {}
                        if (new ConvertStringToStringReturningClass(theProgram, new StringReceiver() {
                              public void receive(String classThatReturnsString) {
                                    if (new Print(classThatReturnsString + "\n") == null) {}
                              }}, new StringBuffer()) == null) {}
                  }}) == null) {}
      }
}

class Print {
      Print(String str) {
            if (new Invoke(System.out, "print", new Class[] {String.class}, new Object[] {str}) == null) {}
      }
}

class ForEachChar {
      ForEachChar(String str, Do doBlock) {
            if (new Body(str, doBlock, 0) == null) {}
      }

      static class Body {
            Body(String str, Do doBlock, int i) {
                  while (i < str.length()) {
                        if (new Invoke(doBlock, "run", new Class[] {char.class},
                                    new Object[] {new Character(str.charAt(i))}) == null) {}
                        if ((++i) == 0) {}
                  }
            }
      }
}

class Do {
      public void run(char c) {}
}

class Invoke {
      Invoke (Object thiz, String methodName, Class[] paramTypes, Object[] args) {
            try {
                  if (thiz.getClass().getMethod(methodName, paramTypes).invoke(thiz, args) == null) {}
            }
            catch (Exception e) {
            }
      }
}

class ConvertStringToStringReturningClass {
      ConvertStringToStringReturningClass(String str, StringReceiver sr, final StringBuffer buff) {
            if (buff.append(
"//Call this method to get the string that represents (most of) the program, except for this\n" + 
"//class itself.\n" + 
"class GetProgramString {\n" + 
"       GetProgramString(StringReceiver sr) {\n" + 
"             if (new Invoke(sr, \"receive\", new Class[] {String.class}, new Object[] {\n" +
"\"") == null) {}
            if (new ForEachChar(str, new Do() {
                  public void run(char c) {
                        if (c == '\"' || c == '\'' || c == '\\') {
                              if (buff.append("\\") == null) {}
                              if (buff.append(c) == null) {}
                        }
                        else if (c == '\n') {
                              if (buff.append("\\n\" + \n\"") == null) {}
                        }
                        else {
                              if (buff.append(c) == null) {}
                        }
                  }}) == null) {}
            if (buff.append(
"\"\n" +
"             }) == null) {}\n" + 
"       }\n" + 
"}\n") == null) {}
            if (new Invoke(sr, "receive", new Class[] {String.class}, new Object[] {buff.toString()}) == null) {}
      }
}

class StringReceiver {
      public void receive(String str) {}
}

//Call this method to get the string that represents (most of) the program, except for this
//class itself.
class GetProgramString {
      GetProgramString(StringReceiver sr) {
            if (new Invoke(sr, "receive", new Class[] {String.class}, new Object[] {
"public class Quine {\n" + 
"       public static void main(String[] args) {\n" + 
"             if (new GetProgramString(new StringReceiver() {\n" + 
"                   public void receive(String theProgram) {\n" + 
"                         if (new Print(theProgram + \"\\n\\n\") == null) {}\n" + 
"                         if (new ConvertStringToStringReturningClass(theProgram, new StringReceiver() {\n" + 
"                               public void receive(String classThatReturnsString) {\n" + 
"                                     if (new Print(classThatReturnsString + \"\\n\") == null) {}\n" + 
"                               }}, new StringBuffer()) == null) {}\n" + 
"                   }}) == null) {}\n" + 
"       }\n" + 
"}\n" + 
"\n" + 
"class Print {\n" + 
"       Print(String str) {\n" + 
"             if (new Invoke(System.out, \"print\", new Class[] {String.class}, new Object[] {str}) == null) {}\n" + 
"       }\n" + 
"}\n" + 
"\n" + 
"class ForEachChar {\n" + 
"       ForEachChar(String str, Do doBlock) {\n" + 
"             if (new Body(str, doBlock, 0) == null) {}\n" + 
"       }\n" + 
"       \n" + 
"       static class Body {\n" + 
"             Body(String str, Do doBlock, int i) {\n" + 
"                   while (i < str.length()) {\n" + 
"                         if (new Invoke(doBlock, \"run\", new Class[] {char.class},\n" + 
"                                     new Object[] {new Character(str.charAt(i))}) == null) {}\n" + 
"                         if ((++i) == 0) {}\n" + 
"                   }\n" + 
"             }\n" + 
"       }\n" + 
"}\n" + 
"\n" + 
"class Do {\n" + 
"       public void run(char c) {}\n" + 
"}\n" + 
"\n" + 
"class Invoke {\n" + 
"       Invoke (Object thiz, String methodName, Class[] paramTypes, Object[] args) {\n" + 
"             try {\n" + 
"                   if (thiz.getClass().getMethod(methodName, paramTypes).invoke(thiz, args) == null) {}\n" + 
"             }\n" + 
"             catch (Exception e) {\n" + 
"             }\n" + 
"       }\n" + 
"}\n" + 
"\n" + 
"class ConvertStringToStringReturningClass {\n" + 
"       ConvertStringToStringReturningClass(String str, StringReceiver sr, final StringBuffer buff) {\n" + 
"             if (buff.append(\n" + 
"\"//Call this method to get the string that represents (most of) the program, except for this\\n\" + \n" + 
"\"//class itself.\\n\" + \n" + 
"\"class GetProgramString {\\n\" + \n" + 
"\"     GetProgramString(StringReceiver sr) {\\n\" + \n" + 
"\"           if (new Invoke(sr, \\\"receive\\\", new Class[] {String.class}, new Object[] {\\n\" +\n" + 
"\"\\\"\") == null) {}\n" + 
"             if (new ForEachChar(str, new Do() {\n" + 
"                   public void run(char c) {\n" + 
"                         if (c == \'\\\"\' || c == \'\\\'\' || c == \'\\\\\') {\n" + 
"                               if (buff.append(\"\\\\\") == null) {}\n" + 
"                               if (buff.append(c) == null) {}\n" + 
"                         }\n" + 
"                         else if (c == \'\\n\') {\n" + 
"                               if (buff.append(\"\\\\n\\\" + \\n\\\"\") == null) {}\n" + 
"                         }\n" + 
"                         else {\n" + 
"                               if (buff.append(c) == null) {}\n" + 
"                         }\n" + 
"                   }}) == null) {}\n" + 
"             if (buff.append(\n" + 
"\"\\\"\\n\" +\n" + 
"\"           }) == null) {}\\n\" + \n" + 
"\"     }\\n\" + \n" + 
"\"}\\n\") == null) {}\n" + 
"             if (new Invoke(sr, \"receive\", new Class[] {String.class}, new Object[] {buff.toString()}) == null) {}\n" + 
"       }\n" + 
"}\n" + 
"\n" + 
"class StringReceiver {\n" + 
"       public void receive(String str) {}\n" + 
"}"
            }) == null) {}
      }
}
Items of interest in this solution: Thanks!

Part of Macneil Shonle's Home Page. Copyright © 2006-2008. All rights reserved.